Recently, the company used UNIApp to develop wechat applets. For the function of login authorization of wechat applets, the method invocation and encapsulation are recorded here.

Implementation steps

Enter applets

When entering the project, the application life cycle of UNIApp will be entered. Add the following code to the OnLaunch method in @/ app. vue.

onLaunch: async function() {
    const login_res = await login()
    await wxLogin(login_res)
}
Copy the code

Call the UI.login () interface

// Call ui.login() to get the user's code
export const login = () = > {
	return new Promise((resolve, reject) = > {
		uni.login({
			provider: 'weixin'.success: res= > {
				resolve(res)
			},
			fail: err= >{ reject(err) } }); })}Copy the code

Return value format

{
	code: "031iOKFa14UxVA0fwnFa1yP9r81iOKFu"
	errMsg: "login:ok"
}
Copy the code

Call the login interface on the back end and send the code

Invokes the back-end login interface, sends the code, toEKN if there is one, carries the token, and returns the latest token and authorization results.

export const wxLogin = (loginRes) = > {
	return new Promise((resolve, reject) = > {
		const {
			errMsg,
			code
		} = loginRes
		if (errMsg.indexOf('ok')! = = -1) {
			validLogin({
				code,
				sf: '1'
			}).then(res= > {
				const {
					code,
					data,
					token
				} = res
				if (code === API_RETURN_CODE.USER_UNLOGIN.code) {
					// The user does not log in to the storage state and stores the returned wechat openId
					uni.setStorageSync(STORAGE_KEYS.USER_LOGIN_CODE, code)
					uni.setStorageSync(STORAGE_KEYS.WX_OPEN_ID, data)
				} else if (code === API_RETURN_CODE.USER_LOGINED.code) {
					// The user has logged in and is not authorized
					uni.setStorageSync(STORAGE_KEYS.USER_LOGIN_CODE, code)
					token && setToken(token)
					const userInfo = {
						phoneNumber: data.phone,
						sf: data.sf
					}
					uni.setStorageSync(STORAGE_KEYS.USER_INFO, userInfo)
				} else if(code === API_RETURN_CODE.USER_AUTHOR.code) {
					// The user has logged in and is authorized
					uni.setStorageSync(STORAGE_KEYS.USER_LOGIN_CODE, code)
					token && setToken(token)
					const userInfo = {
						phoneNumber: data.phone,
						sf: data.sf
					}
					uni.setStorageSync(STORAGE_KEYS.USER_INFO, userInfo)
				} 
				resolve()
			}).catch((err) = > {
				console.log(err);
				reject()
			})
		} else if (errMsg.indexOf('fail')! = = -1) {
			uni.showToast({
				title: 'Wx. login error, please exit and re-enter'.duration: 2000
			})
			reject()
		}
	})
}

Copy the code

The page for verifying login status and authorization status is displayed

If you have not logged in, the login page is displayed. If you have logged in but are not authorized, an authorization dialog box is displayed. If you have logged in and been authorized, return to the status and go to the page. Invoke the following method on the page where you need to verify login and authorization status:

checkUserAuth()
.then(res= > {
	if(res.status ! = =' ') {
		this.authStatusText = res.status;
	}
})
.catch(err= > {
	console.log(err);
});

Copy the code

(PS: I need to judge the state when the page is displayed, so I call this method in the onShow function. The specific location of the call needs to be analyzed according to the needs.)

Check the login status and authorization status of the user

// Check the user login status
export const checkUserAuth = () = > {
	return new Promise((resolve, reject) = > {
		// The user login code
		const userLoginCode = uni.getStorageSync(STORAGE_KEYS.USER_LOGIN_CODE)
		const returnRes = {
			code: 0.status: ' '.message: ' '
		}
		if(! userLoginCode) { returnRes.code = userLoginCode returnRes.message ='Login status code not obtained'
			reject(returnRes)
		} else if (userLoginCode === API_RETURN_CODE.USER_ERROR.code) {
			returnRes.code = userLoginCode
			returnRes.message = 'abnormal'
			reject(returnRes)
		} else if (userLoginCode === API_RETURN_CODE.USER_AUTHOR.code) {
			// The user has logged in and is authorized
			returnRes.code = userLoginCode
			returnRes.status = 'Logged in, authorized'
			resolve(returnRes)
		} else if (userLoginCode === API_RETURN_CODE.USER_LOGINED.code) {
			// The user is logged in and not authorized
			uni.showModal({
				title: 'tip'.content: 'Your account is not authorized. Do you want to authorize it? '.success: function(res) {
					if (res.confirm) {
						getUserProfile().then(async infoRes => {
							const saveAuthRes = await saveAuthInfo(infoRes)
							returnRes.code = userLoginCode
							returnRes.status = 'Logged in, authorized'
							resolve(returnRes)
						}).catch(err= > {
							console.log(err); })}else if (res.cancel) {
						returnRes.code = userLoginCode
						returnRes.status = 'Logged in, not authorized'
						resolve(returnRes)
					}
				}
			});
		} else if (userLoginCode === API_RETURN_CODE.USER_UNLOGIN.code) {
			// If you have not logged in, go to the login page
			uni.showModal({
				title: 'tip'.content: 'You are not logged in. Are you logged in? '.success: function(res) {
					returnRes.code = userLoginCode
					returnRes.status = 'Not logged in'
					if (res.confirm) {
						uni.navigateTo({
							url: 'pages/login/index'})},else if(res.cancel) {} resolve(returnRes) } }); }})}Copy the code

Obtain user information authorization

In the previous step, if you have logged in but are not authorized, the authorization dialog box is displayed. The uni.getUserProfile() interface needs to be called, and the obtained user information is sent to the back end and the authorization information is saved.

Call the uni. GetUserProfile ()

// Get user information. An authorization window pops up for each request, and userInfo is returned after the user agrees.
export const getUserProfile = () = > {
	return new Promise((resolve, reject) = > {
		uni.getUserProfile({
			desc: 'User Login'.success: (info_res) = > {
				resolve(info_res)
			},
			fail: err= > {
				reject(err)
			}
		})
	})
}

Copy the code

Saving Authorization Information

// 6. Save authorization information
export const saveAuthInfo = (info) = > {
	return new Promise((resolve, reject) = > {
		const {
			nickName,
			gender,
			city,
			province,
			country,
			avatarUrl
		} = info.userInfo
		
		const data = {
			nickName: nickName,
			avatarUrl: avatarUrl,
			gender: gender,
			address: `${city === ' ' ? '0' : city} ${province === ' ' ? '0' : province} ${country === ' ' ? '0' : country}`
		}
		saveWXAuthInfo(data).then(res= > {
			uni.setStorageSync(STORAGE_KEYS.USER_LOGIN_CODE, res.code)
			resolve()
		}).catch(err= > {
			reject(err)
		})
	})
}

Copy the code

User one-click login (obtain mobile phone number)

If the login status is not verified, the login page is displayed.

Login page code

<! -- #ifdef MP-WEIXIN -->
<button 
    class="login-btn" 
    type="primary" 
    plain="true" 
    open-type="getPhoneNumber" 
    @getphonenumber="getPhoneNumber">Wechat one-click login</button><! -- #endif -->
Copy the code
// add methods to methods
getPhoneNumber(res) {
    getPhoneNumber(res).then(() = > {
        sendPhoneLogin(res.detail).then(() = > {
            uni.navigateBack()			
        }).catch(() = > {})
    }).catch(err= > {console.log(err); }); }Copy the code

Get the user’s mobile phone number and send it to the back end

// Get the phone number
// Process the getPhoneNubmber operation, reject if it fails
export const getPhoneNumber = (res) = > {
	return new Promise((resolve, reject) = > {
		console.log(res);
		const {
			detail
		} = res;
		0: the user has refused
		if (detail.errMsg.indexOf('ok')! = = -1) {
			resolve(res)
		} else if (detail.errMsg.indexOf('fail')! = = -1) {
			reject(detail.errMsg)
		}
	})
}


// 15. After obtaining the phone number, send the relevant information to the back end
export const sendPhoneLogin = (info) = > {
	return new Promise((resolve, reject) = > {
		const data = {
			sf: '1'.encryptedData: info.encryptedData,
			iv: info.iv,
			openId: uni.getStorageSync(STORAGE_KEYS.WX_OPEN_ID)
		}
		phoneLogin(data).then((res) = > {
			const {
				code,
				data,
				token
			} = res
			if(code === API_RETURN_CODE.USER_ERROR.code) {
				reject(code)
			}
			const userInfo = {
				phoneNumber: data.phone,
				sf: data.sf
			}
			uni.setStorageSync(STORAGE_KEYS.USER_INFO, userInfo)
			uni.setStorageSync(STORAGE_KEYS.USER_LOGIN_CODE, code)
			setToken(token)
			resolve(res)
		}).catch(() = > {
			reject()
		})
	})
}
Copy the code

Related to the interface

import request from '@/utils/request.js'

export const validLogin = (params) = > {
	return request.get('/wx/validLogin', params)
}


export const saveWXAuthInfo = (data) = > {
	return request.post('/wx/saveUserProfile', data, {
		header: {
			'content-type': 'application/x-www-form-urlencoded',}})}export const phoneLogin = (data) = > {
	return request.post('/wx/phoneLogin', data, {
		// dataType: '',
		header: {
			'content-type': 'application/x-www-form-urlencoded',}})}Copy the code

Related code files

  • SetToken encapsulation

  • MiniRequest encapsulation

  • The request to encapsulate

  • Wx correlation method encapsulation

  • Constant encapsulation