添加基础登录逻辑 review by 黄敬囿
Showing
6 changed files
with
248 additions
and
13 deletions
src/libs/login/login.js
0 → 100644
1 | +import { LoginService } from './loginService.js' | ||
2 | + | ||
3 | +const login = new LoginService().yohoApi(); | ||
4 | + | ||
5 | +export const loginAction = (callBack) => { | ||
6 | + return wx.login({ | ||
7 | + success(res) { | ||
8 | + if (res.code) { | ||
9 | + login.checkLogin(res.code).then((data) => { | ||
10 | + // 获取 srd_session | ||
11 | + const loginData = data; | ||
12 | + handleLoginData(loginData); | ||
13 | + callBack(null, data); | ||
14 | + }).catch((error) => { | ||
15 | + callBack(error); | ||
16 | + }); | ||
17 | + } | ||
18 | + }, | ||
19 | + fail(error) { | ||
20 | + callBack(error); | ||
21 | + } | ||
22 | + }) | ||
23 | +}; | ||
24 | + | ||
25 | +const handleLoginData = (loginData) => { | ||
26 | + // 上报接口返回的结果,线上debug用 | ||
27 | + // 缓存 srd_session | ||
28 | + setStorageWithValueForKey('srd_session', loginData.srd_session); | ||
29 | + // 缓存 openid | ||
30 | + setStorageWithValueForKey('openid', loginData.openid); | ||
31 | + // 如果 unionid 不存在(未使用过任何有货微信产品的全新用户),调用getUnionID函数,再次获取unionID | ||
32 | + if (loginData.unionid) { | ||
33 | + // 对于已经授权过的用户,拿到unionid之后获取一次userinfo更新个人信息 | ||
34 | + setStorageWithValueForKey('unionid', loginData.unionid); | ||
35 | + } | ||
36 | +} | ||
37 | + | ||
38 | +/** | ||
39 | + * 判断微信用户是否绑定 | ||
40 | + * @param srd_session | ||
41 | + * @param result | ||
42 | + * @returns {Promise.} | ||
43 | + */ | ||
44 | +export const decodeUnionId = (srd_session, result) => { | ||
45 | + let res = result.detail; | ||
46 | + // 存储 userInfo | ||
47 | + if (res && res.userInfo) { | ||
48 | + setStorageWithValueForKey('userInfo', res.userInfo); | ||
49 | + } else { | ||
50 | + return; | ||
51 | + } | ||
52 | + const nickName = res.userInfo.nickName; | ||
53 | + const avatarUrl = res.userInfo.avatarUrl; | ||
54 | + if (!srd_session) return; | ||
55 | + return login.getUnionID(srd_session, res.encryptedData, res.iv).then((data) => { | ||
56 | + let union_id; | ||
57 | + // 本地保存 union_id | ||
58 | + if (data.union_id) { | ||
59 | + setStorageWithValueForKey('union_id', data.union_id); | ||
60 | + union_id = data.union_id; | ||
61 | + } else { | ||
62 | + union_id = wx.getStorageSync('union_id'); | ||
63 | + } | ||
64 | + if (!union_id) { | ||
65 | + throw new Error('union_id is null'); | ||
66 | + } | ||
67 | + // 网络上传头像,union_id,昵称 | ||
68 | + login.sendWeChatUserDataWithUnionId(data.union_id, nickName, avatarUrl).catch(error => {}); | ||
69 | + return { | ||
70 | + union_id: union_id, | ||
71 | + userInfo: res.userInfo | ||
72 | + }; | ||
73 | + }); | ||
74 | +}; | ||
75 | + | ||
76 | +/** | ||
77 | + * 判断微信用户是否绑定 | ||
78 | + * @param unionID | ||
79 | + * @param userInfo | ||
80 | + * @returns {Promise.} | ||
81 | + */ | ||
82 | +export const wechatUserIsBind = (union_id, userInfo) => { | ||
83 | + return login.wechatUserIsBind(union_id, userInfo.nickName).then(data => { | ||
84 | + if (!isStringEmpty(data.is_bind) && data.is_bind === "Y") { | ||
85 | + const newUserInfo = { | ||
86 | + is_bind: data.is_bind, | ||
87 | + mobile: data.mobile, | ||
88 | + session_key: data.session_key, | ||
89 | + uid: data.uid, | ||
90 | + ssouid: data.ssouid | ||
91 | + }; | ||
92 | + const assignUserInfo = Object.assign(newUserInfo, userInfo); | ||
93 | + setStorageWithValueForKey('userInfo', assignUserInfo); | ||
94 | + | ||
95 | + return Promise.resolve({ | ||
96 | + code: 10003, | ||
97 | + data: userInfo, | ||
98 | + message: '微信用户已绑定手机号' | ||
99 | + }); | ||
100 | + } else { | ||
101 | + return Promise.resolve({ | ||
102 | + code: 10004, | ||
103 | + message: '微信用户未绑定手机号' | ||
104 | + }); | ||
105 | + } | ||
106 | + }); | ||
107 | +} | ||
108 | + | ||
109 | +const setStorageWithValueForKey = (key, value) => { | ||
110 | + const globalData = getGlobalData(); | ||
111 | + wx.setStorage({ | ||
112 | + key: key, | ||
113 | + data: value, | ||
114 | + }) | ||
115 | + globalData[key] = value; | ||
116 | +} | ||
117 | + | ||
118 | +const getStorageWithValueForKey = (key) => { | ||
119 | + wx.getStorage({ | ||
120 | + key: key, | ||
121 | + success: function(res) { | ||
122 | + | ||
123 | + }, | ||
124 | + }) | ||
125 | +} | ||
126 | + | ||
127 | +const getGlobalData = () => { | ||
128 | + const app = getApp(); | ||
129 | + let globalData; | ||
130 | + if (app && app.globalData) { | ||
131 | + // 原生小程序的 globalData 获取方式 | ||
132 | + globalData = app && app.globalData; | ||
133 | + } else { | ||
134 | + // Taro 下 globalData 获取方式 | ||
135 | + globalData = app && app.props && app.props.globalData; | ||
136 | + } | ||
137 | + return globalData; | ||
138 | +} | ||
139 | + | ||
140 | +const isStringEmpty = (str) => { | ||
141 | + if (str === undefined || str === null || str === '') { | ||
142 | + return true | ||
143 | + } else { | ||
144 | + return false | ||
145 | + } | ||
146 | +} |
src/libs/login/loginService.js
0 → 100644
1 | +import BaseService from '../services/baseService.js'; | ||
2 | + | ||
3 | +const WECHAT_SMALLPROGRAM_ONLOGIN = 'wechat.smallProgram.onLogin'; | ||
4 | +const WECHAT_SMALLPROGRAM_DECODEUSERINFO = 'wechat.smallProgram.decodeUserInfo'; | ||
5 | +const WECHAT_ADDUNIONUPDUSER = 'app.wechat.addUnionUpdUser'; | ||
6 | +const WECHAT_PASSPORT_SIGNINBYOPENID = 'app.passport.signinByOpenID'; | ||
7 | + | ||
8 | +const WechatPath = '/wechat'; | ||
9 | + | ||
10 | +export class LoginService extends BaseService { | ||
11 | + async checkLogin(code) { | ||
12 | + return await this.GET({ | ||
13 | + method: WECHAT_SMALLPROGRAM_ONLOGIN, | ||
14 | + jsCode: code, | ||
15 | + miniapp_type: '0' // 暂时为 0 | ||
16 | + }, { | ||
17 | + path: WechatPath | ||
18 | + }).then((data) => { | ||
19 | + return data; | ||
20 | + }).catch((error) => { | ||
21 | + throw error; | ||
22 | + }) | ||
23 | + } | ||
24 | + | ||
25 | + async getUnionID(srdSession, encryptedData, iv) { | ||
26 | + return await this.GET({ | ||
27 | + method: WECHAT_SMALLPROGRAM_DECODEUSERINFO, | ||
28 | + srdSession, | ||
29 | + encryptedData, | ||
30 | + iv | ||
31 | + }, { | ||
32 | + path: WechatPath | ||
33 | + }).then((data) => { | ||
34 | + return data; | ||
35 | + }).catch((error) => { | ||
36 | + throw error; | ||
37 | + }); | ||
38 | + } | ||
39 | + | ||
40 | + async sendWeChatUserDataWithUnionId(unionId, nickname, avatarUrl) { | ||
41 | + if (!unionId || !nickname || !avatarUrl || avatarUrl === "images/mine_default_head.png") throw new Error('请检查 unionId 或用户信息是否有误'); | ||
42 | + return await this.GET({ | ||
43 | + method: WECHAT_ADDUNIONUPDUSER, | ||
44 | + unionId, | ||
45 | + headIco: avatarUrl, | ||
46 | + nickname | ||
47 | + }).then(data => { | ||
48 | + return data; | ||
49 | + }).catch(error => { | ||
50 | + throw error; | ||
51 | + }) | ||
52 | + } | ||
53 | + | ||
54 | + async wechatUserIsBind(unionId, nickname) { | ||
55 | + return await this.GET({ | ||
56 | + method: WECHAT_PASSPORT_SIGNINBYOPENID, | ||
57 | + openId: unionId, | ||
58 | + nickname | ||
59 | + }).then(data => { | ||
60 | + return data | ||
61 | + }).catch(error => { | ||
62 | + throw error; | ||
63 | + }); | ||
64 | + } | ||
65 | +} |
@@ -4,7 +4,7 @@ import trimObject from './utils/trimObject.js' | @@ -4,7 +4,7 @@ import trimObject from './utils/trimObject.js' | ||
4 | import queryString from './utils/query-string/query-string.js' | 4 | import queryString from './utils/query-string/query-string.js' |
5 | const crypto = require('./utils/cryptojs/cryptojs.js'); | 5 | const crypto = require('./utils/cryptojs/cryptojs.js'); |
6 | import MD5 from './utils/md5/md5.js' | 6 | import MD5 from './utils/md5/md5.js' |
7 | - | 7 | +import udid from './utils/udid.js' |
8 | 8 | ||
9 | const request = (methods = 'GET') => { | 9 | const request = (methods = 'GET') => { |
10 | return async (options = {}) => { | 10 | return async (options = {}) => { |
@@ -46,7 +46,7 @@ const handleParam = (params) => { | @@ -46,7 +46,7 @@ const handleParam = (params) => { | ||
46 | let globalData = getGlobalData(); | 46 | let globalData = getGlobalData(); |
47 | getUid(params); | 47 | getUid(params); |
48 | getUdid(params); | 48 | getUdid(params); |
49 | - const session_key = globalData && globalData.sessionKey ? globalData.sessionKey : ''; | 49 | + const session_key = globalData && globalData.userInfo && globalData.userInfo.session_key ? globalData.userInfo.session_key : ''; |
50 | const publicParams = _publicParams(); | 50 | const publicParams = _publicParams(); |
51 | let newParams = { | 51 | let newParams = { |
52 | ...params, | 52 | ...params, |
@@ -59,16 +59,7 @@ const handleParam = (params) => { | @@ -59,16 +59,7 @@ const handleParam = (params) => { | ||
59 | } | 59 | } |
60 | 60 | ||
61 | const getUdid = (params) => { | 61 | const getUdid = (params) => { |
62 | - const globalData = getGlobalData(); | ||
63 | - if (params && !params.hasOwnProperty('udid')) { | ||
64 | - let udid = globalData.udid ? globalData.udid : ""; | ||
65 | - if (udid.length === 0) { | ||
66 | - udid = getYHStorageSync('udid', 'request'); | ||
67 | - } | ||
68 | - if (udid.length !== 0) { | ||
69 | - params.udid = udid; | ||
70 | - } | ||
71 | - } | 62 | + params.udid = udid.get(); |
72 | } | 63 | } |
73 | 64 | ||
74 | const getUid = (params) => { | 65 | const getUid = (params) => { |
@@ -130,6 +121,7 @@ const handleHeader = (options, newParams) => { | @@ -130,6 +121,7 @@ const handleHeader = (options, newParams) => { | ||
130 | const session_key = newParams.session_key ? newParams.session_key : ''; | 121 | const session_key = newParams.session_key ? newParams.session_key : ''; |
131 | let header = { | 122 | let header = { |
132 | 'x-yoho-verify': resultString, | 123 | 'x-yoho-verify': resultString, |
124 | + 'Cookie': 'JSESSIONID=' + session_key, | ||
133 | 'Cookies': 'JSESSIONID=' + session_key, | 125 | 'Cookies': 'JSESSIONID=' + session_key, |
134 | } | 126 | } |
135 | return header; | 127 | return header; |
@@ -159,7 +151,7 @@ const sendRequest = (resolve, reject, options) => { | @@ -159,7 +151,7 @@ const sendRequest = (resolve, reject, options) => { | ||
159 | const statusCode = res.statusCode; | 151 | const statusCode = res.statusCode; |
160 | const errMsg = res.errMsg; | 152 | const errMsg = res.errMsg; |
161 | const data = res.data; | 153 | const data = res.data; |
162 | - if (data && data.code == 200 && data.data) { | 154 | + if (data && (data.code == 200 || data.code == 301) && data.data) { |
163 | resolve(data.data); | 155 | resolve(data.data); |
164 | } else { | 156 | } else { |
165 | const code = res.statusCode; | 157 | const code = res.statusCode; |
src/libs/request/utils/udid.js
0 → 100644
src/libs/request/utils/uuid.js
0 → 100644
1 | +// github: https://github.com/kelektiv/node-uuid | ||
2 | +// update: https://wzrd.in/standalone/uuid%2Fv4@latest | ||
3 | +!function(r){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=r();else if("function"==typeof define&&define.amd)define([],r);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.uuidv4=r()}}(function(){return function r(e,n,t){function o(f,u){if(!n[f]){if(!e[f]){var a="function"==typeof require&&require;if(!u&&a)return a(f,!0);if(i)return i(f,!0);var d=new Error("Cannot find module '"+f+"'");throw d.code="MODULE_NOT_FOUND",d}var p=n[f]={exports:{}};e[f][0].call(p.exports,function(r){var n=e[f][1][r];return o(n?n:r)},p,p.exports,r,e,n,t)}return n[f].exports}for(var i="function"==typeof require&&require,f=0;f<t.length;f++)o(t[f]);return o}({1:[function(r,e,n){function t(r,e){var n=e||0,t=o;return t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]}for(var o=[],i=0;i<256;++i)o[i]=(i+256).toString(16).substr(1);e.exports=t},{}],2:[function(r,e,n){var t="undefined"!=typeof crypto&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&msCrypto.getRandomValues.bind(msCrypto);if(t){var o=new Uint8Array(16);e.exports=function(){return t(o),o}}else{var i=new Array(16);e.exports=function(){for(var r,e=0;e<16;e++)0===(3&e)&&(r=4294967296*Math.random()),i[e]=r>>>((3&e)<<3)&255;return i}}},{}],3:[function(r,e,n){function t(r,e,n){var t=e&&n||0;"string"==typeof r&&(e="binary"===r?new Array(16):null,r=null),r=r||{};var f=r.random||(r.rng||o)();if(f[6]=15&f[6]|64,f[8]=63&f[8]|128,e)for(var u=0;u<16;++u)e[t+u]=f[u];return e||i(f)}var o=r("./lib/rng"),i=r("./lib/bytesToUuid");e.exports=t},{"./lib/bytesToUuid":1,"./lib/rng":2}]},{},[3])(3)}); |
@@ -6,6 +6,7 @@ import searchImg from '../../static/images/search.png'; | @@ -6,6 +6,7 @@ import searchImg from '../../static/images/search.png'; | ||
6 | import {common as commonModel} from '../../models'; | 6 | import {common as commonModel} from '../../models'; |
7 | import './index.scss'; | 7 | import './index.scss'; |
8 | import { connect } from '@tarojs/redux'; | 8 | import { connect } from '@tarojs/redux'; |
9 | +import { loginAction, decodeUnionId, wechatUserIsBind } from '../../libs/login/login.js' | ||
9 | 10 | ||
10 | 11 | ||
11 | @connect(({ filterMenu }) => ({ | 12 | @connect(({ filterMenu }) => ({ |
@@ -116,6 +117,18 @@ export default class Index extends Component { | @@ -116,6 +117,18 @@ export default class Index extends Component { | ||
116 | }) | 117 | }) |
117 | } | 118 | } |
118 | 119 | ||
120 | + login(e) { | ||
121 | + loginAction((error, loginData) => { | ||
122 | + if (error) return; | ||
123 | + decodeUnionId(loginData.srd_session, e).then(data => { | ||
124 | + console.log(data); | ||
125 | + wechatUserIsBind(data.union_id, data.userInfo).then(message => { | ||
126 | + console.log(message); | ||
127 | + }); | ||
128 | + }); | ||
129 | + }) | ||
130 | + } | ||
131 | + | ||
119 | render() { | 132 | render() { |
120 | let {tabs, productList} = this.state; | 133 | let {tabs, productList} = this.state; |
121 | let {filterMenu} = this.props; | 134 | let {filterMenu} = this.props; |
@@ -133,6 +146,7 @@ export default class Index extends Component { | @@ -133,6 +146,7 @@ export default class Index extends Component { | ||
133 | <View className="header-nav"> | 146 | <View className="header-nav"> |
134 | <Text className="page-label">飞碟好物</Text> | 147 | <Text className="page-label">飞碟好物</Text> |
135 | <Text onClick={this.gotoNative}>跳转原生页面</Text> | 148 | <Text onClick={this.gotoNative}>跳转原生页面</Text> |
149 | + <Button openType="getUserInfo" onGetUserInfo={this.login}>登录</Button> | ||
136 | <Navigator url="/pages/search/index" className="search" hover-class="none"><Image className="search-btn" src={searchImg}></Image></Navigator> | 150 | <Navigator url="/pages/search/index" className="search" hover-class="none"><Image className="search-btn" src={searchImg}></Image></Navigator> |
137 | </View> | 151 | </View> |
138 | 152 |
-
Please register or login to post a comment