美文网首页ionic2ionic
ionic2/3中http请求的封装和加密

ionic2/3中http请求的封装和加密

作者: 谢大见 | 来源:发表于2017-07-12 17:15 被阅读189次

    项目要求接口概述:

    1.请求协议

    1. HTTP+JSON
    2. HTTPS+JSON

    2.接口安全

    报文合法性验证

    1. 取出所有参数及值(公共及所有的业务参数),按参数名称的大小写字母序由小到大排列得到A1;
      注:格式如: key1=value1&key2=value2&key3=value3
    2. 将A1 + timestamp拼接为一个字符串,得到A2
      注:如果没有业务参数,则直接用timestamp即可。
    3. 用MD5算法对A2做散列得到A3
    4. 将A3 + userName再拼接成一个字符串,得到A4(如果此时用户未登陆无userName,则为空)
    5. 用MD5算法对A4做散列得到签名值:sign
      注:
    6. MD5(MD5(“key1=value1&key2&value2&key3=value3” + timestamp) + userName)
    7. 散列后的MD5字符数组,按16进制转换成字符串。

    需要用到第三方js:



    参考地址:https://github.com/xiedajian/ipvpKmfApp2.0/tree/master/src/assets/js

    核心代码:

    import {Injectable} from '@angular/core';
    import {Http, Response, Headers, RequestOptions} from '@angular/http';
    import {AES_key, AppConfig}from'../app/app.config';
    
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/toPromise';
    /*SHA1散列*/
    declare function SHA1(msg:string);
    /*MD5加密*/
    declare function hex_md5(msg:string);
    /*AES加密*/
    declare var CryptoJS;
    /*RSA加密*/
    declare var RSAUtils;
    
    /**
     * HTTP请求服务
     */
    @Injectable()
    export class HttpSer {
    
        constructor(public http:Http) {
        }
    
        /**
         * get方式请求
         * @param   url:string  paramObj:{name:'大见',age:'23'}
         * @returns Promise
         */
        get(url:string, paramObj:any = {}) {
            let timestamp = this.getTimestamp();
            let sign = this.getSign(paramObj, timestamp);
            let headers = this.getHeader(sign, timestamp);
            let options = new RequestOptions({headers: headers});
            return this.http.get(url + this.toQueryString(paramObj), options)
                .toPromise()
                .then(this.extractData)
                .catch(this.handleError);
        }
    
        /**
         * post方式请求
         * @param   url:string  paramObj:{name:'大见',age:'23'}
         * @returns Promise application/x-www-form-urlencoded
         */
        post(url:string, body:any = {}, contentType:string="application/x-www-form-urlencoded") {
            let timestamp = this.getTimestamp();
            let sign = this.getSign(body, timestamp);
            let headers = this.getHeader(sign, timestamp, contentType);
            let options = new RequestOptions({headers: headers});
            return this.http.post(url, this.toBodyString(body), options)
                .toPromise()
                .then(this.extractData)
                .catch(this.handleError);
        }
    
        /**
         * 登陆App
         * 密码的算法:SHA1(SHA1(密码明文)+请求头中的timestamp)
         * 密码的算法:MD5(MD5(密码明文)+请求头中的timestamp)
         * @param   url:string  body:{userName:'大见',password:'123456'}
         * @returns Promise
         */
        login(url:string, body:any = {}) {
            let timestamp = this.getTimestamp();
            //对密码加密处理
            // let password=SHA1(SHA1(body.password)+timestamp);
            let password = hex_md5(hex_md5(body.password) + timestamp);
            let newbody = {
                userName: body.userName,
                password: password,
            }
            // console.log(url);
            // console.log(newbody);
            let sign = this.getSign(newbody, timestamp);
            let headers = this.getHeader(sign, timestamp);
            let options = new RequestOptions({headers: headers});
            return this.http.post(url, this.toBodyString(newbody), options)
                .toPromise()
                .then(this.extractData)
                .catch(this.handleError);
        }
    
        /**
         * 修改密码 || 重置密码
         * @param   url:string  body:{userName:'大见',password:'123456',newPassword:'654321'} ||  body:{userName:'大见',newPassword:'654321'}
         * @returns Promise
         * 密码的算法:SHA1(SHA1(密码明文)+请求头中的timestamp)
         * 新密码算法:AES(MD5(密码明文))
         * 注:body两个元素为重置密码,三个元素为修改密码
         */
        setNewPassword(url:string, body:any = {}) {
            let timestamp = this.getTimestamp();
            let newbody:any={};
            let vi = this.getVi(timestamp);
            // console.log(vi);
            let newPassword = this.AES_Encrypt(hex_md5(body.newPassword), vi);
            var arr = Object.keys(body);
            // console.log(body);
            // console.log(arr);
            // console.log(body.length);
            // console.log(arr.length);
            if(arr.length==2){
                newbody = {
                    userName: body.userName,
                    newPassword: newPassword,
                }
                console.log('重置密码');
            }else {
                let password = hex_md5(hex_md5(body.password) +''+ timestamp);
                newbody = {
                    userName: body.userName,
                    password: password,
                    newPassword: newPassword,
                }
                console.log('修改密码');
            }
            // console.log(vi);
            // console.log(url);
            // console.log(newbody);
            let sign = this.getSign(newbody, timestamp);
            let headers = this.getHeader(sign, timestamp);
            let options = new RequestOptions({headers: headers});
            return this.http.post(url, this.toBodyString(newbody), options)
                .toPromise()
                .then(this.extractData)
                .catch(this.handleError);
        }
        
        /**
         * 获取当前时间 减 2015年1月1日的 时间戳
         */
        private getTimestamp() {
            let timestamp = Math.floor(new Date().getTime() / 1000 - 1420070400).toString();
            return timestamp;
        }
    
        /**
         * 制作请求头header
         * @param   sign  timestamp
         * @returns headers
         */
        private getHeader(sign:string, timestamp:string, contentType:string="application/x-www-form-urlencoded") {
            let headers:any = new Headers();
            headers.append('content-type', contentType);
            headers.append('token', AppConfig.getToken());
            headers.append('timestamp', timestamp);
            headers.append('platform', AppConfig.getPlatform());
            headers.append('deviceId', AppConfig.getDeviceid());
            headers.append('sign', sign);
            headers.append('appName', AppConfig.getAppName());
            headers.append('appVersion', AppConfig.getAppVersion());
            return headers;
        }
    
        /**
         *  制作签名
         * @param  obj (请求参数),timestamp
         * @return {string}
         *  1.取出所有参数及值(公共及所有的业务参数),按小写字母序由小到大排列得到A1;
         *  2.将A1 + timestamp拼接为一个字符串,得到A2
         *  3.用SHA1算法对A2做散列得到A3
         *  4.将A3 + userName再拼接成一个字符串,得到A4
         *  5.用SHA1算法对A4做散列得到签名值:sign
         */
        private getSign(obj:any = {}, timestamp:string) {
            let ret:any[] = [];
            for (let key in obj) {
                let values = obj[key];
                if (values && values.constructor == Array) {//数组
                    let queryValues = [];
                    for (let i = 0, len = values.length, value; i < len; i++) {
                        value = values[i];
                        queryValues.push(this.toSignPair(key, value));
                    }
                    ret = ret.concat(queryValues);
                } else { //字符串
                    ret.push(this.toSignPair(key, values));
                }
            }
            ret.push(this.toSignPair('token', AppConfig.getToken()));
            ret.push(this.toSignPair('platform', AppConfig.getPlatform()));
            ret.push(this.toSignPair('deviceId', AppConfig.getDeviceid()));
            ret.push(this.toSignPair('appName', AppConfig.getAppName()));
            ret.push(this.toSignPair('appVersion', AppConfig.getAppVersion()));
            ret.sort();
            // let A1:string = ret.join('&');
            // let A2 = A1 + '' + timestamp;
            // let A3 = SHA1(A2);
            // let A4 = A3 + AppConfig.getuserName();
            // let sign = SHA1(A4);
            let A1:string = ret.join('&');
            let A2 = A1 + '' + timestamp;
            let A3 = hex_md5(A2);
            let A4 = A3 + AppConfig.getuserName();
            let sign = hex_md5(A4);
             //console.log('token' + '--' + AppConfig.getToken());
             //console.log(ret);
             // console.log('A1' + '--' + A1);
             // console.log('A2' + '--' + A2);
             // console.log('A3' + '--' + A3);
             // console.log('A4' + '--' + A4);
             // console.log('A5' + '--' + sign);
            return sign;
        }
    
        /**
         * get请求参数处理
         * @param obj 参数对象
         * @return {string} 参数字符串
         * @example
         *  声明: var obj= {'name':'大见',age:23};
         *  调用: toQueryString(obj);
         *  返回: "?name=%E5%B0%8F%E5%86%9B&age=23"
         */
        private toQueryString(obj) {
            let ret = [];
            for (let key in obj) {
                key = encodeURIComponent(key);
                let values = obj[key];
                if (values && values.constructor == Array) {//数组
                    let queryValues = [];
                    for (let i = 0, len = values.length, value; i < len; i++) {
                        value = values[i];
                        queryValues.push(this.toQueryPair(key, value));
                    }
                    ret = ret.concat(queryValues);
                } else { //字符串
                    ret.push(this.toQueryPair(key, values));
                }
            }
            return '?' + ret.join('&');
        }
    
        /**
         *  post请求参数处理
         * @param obj
         * @return {string}
         *  声明: var obj= {'name':'大见',age:23};
         *  调用: toQueryString(obj);
         *  返回: "name=%E5%B0%8F%E5%86%9B&age=23"
         */
        private toBodyString(obj) {
            let ret = [];
            for (let key in obj) {
                key = encodeURIComponent(key);
                // key = key;
                let values = obj[key];
                if (values && values.constructor == Array) {//数组
                    let queryValues = [];
                    for (let i = 0, len = values.length, value; i < len; i++) {
                        value = values[i];
                        queryValues.push(this.toQueryPair(key, value));
                    }
                    ret = ret.concat(queryValues);
                } else { //字符串
                    ret.push(this.toQueryPair(key, values));
                }
            }
            return ret.join('&');
        }
    
        private toQueryPair(key, value) {
            if (typeof value == 'undefined') {
                return key;
            }
            return key + '=' + encodeURIComponent(value === null ? '' : String(value));
            // return key + '=' +(value === null ? '' : String(value));
        }
    
        private toSignPair(key, value) {
            return key + '=' + (value === null ? '' : String(value));
        }
    
        private extractData(res:Response) {
            let body = res.json();
            return body || {};
        }
    
        private handleError(error:Response | any) {
            let errMsg:string;
            if (error instanceof Response) {
                const body = error.json() || '';
                const err = body.error || JSON.stringify(body);
                errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
            } else {
                errMsg = error.message ? error.message : error.toString();
            }
            console.error(errMsg);
            return Promise.reject(errMsg);
        }
    
    
        /**
         * AES加密
         * @param   word:string(需要加密的字符)  iv:string(秘钥偏移量)
         * @returns String
         * 注:需要秘钥(AES_key)和秘钥偏移量(iv)
         */
        public AES_Encrypt(word, iv) {
            var key = CryptoJS.enc.Utf8.parse(AES_key);
            var iv  = CryptoJS.enc.Utf8.parse(iv);
            var srcs = CryptoJS.enc.Utf8.parse(word);
            var encrypted = CryptoJS.AES.encrypt(srcs, key, {
                iv: iv,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            });
            return encrypted.ciphertext.toString().toUpperCase();
        }
    
        /**
         * AES解密
         * @param   word:string(需要解密的字符)  iv:string(秘钥偏移量)
         * @returns String
         * 注:需要秘钥(AES_key)和秘钥偏移量(iv)
         */
        public AES_Decrypt(word, iv) {
            var encryptedHexStr = CryptoJS.enc.Hex.parse(word);
            var srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
            var decrypt = CryptoJS.AES.decrypt(srcs, AES_key, {
                iv: iv,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            });
            var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
            return decryptedStr.toString();
        }
    
        //制作秘钥偏移量(iv)
        /**
         * 制作AES秘钥偏移量(iv)
         * @param   timestamp:string(时间戳) 
         * @returns String
         * 注:iv=timestamp+年月日
         */
        public  getVi(timestamp) {
            let date = new Date();
            let month:any = date.getMonth() + 1;
            let strDate:any = date.getDate();
            if (month >= 1 && month <= 9) {
                month = "0" + month;
            }
            if (strDate >= 0 && strDate <= 9) {
                strDate = "0" + strDate;
            }
            let iv:string = timestamp + "" + date.getFullYear() + "" + month + "" + strDate;
            return iv;
        }
    }
    

    相关文章

      网友评论

        本文标题:ionic2/3中http请求的封装和加密

        本文链接:https://www.haomeiwen.com/subject/adwbhxtx.html