当前位置:网站首页>Implementation of code scanning login
Implementation of code scanning login
2022-06-28 08:42:00 【ZhiXiongWu】
Preface
In this article, we will introduce the method based on SpringBoot + Vue + Android Code scanning login demo General idea of , Implement some references What's the principle of QR code scanning login .
Project brief introduction
Back end :SpringBoot,Redis.
front end :Vue,Vue Router、VueX、Axios、vue-qr、ElemntUI.
Android :ZXing、XUI、YHttp
Realize the idea
Overall code scanning login and OAuth2.0 The validation logic of is similar , As shown below :

The user's choice of code scanning login can be regarded as A: The front end sends an authorization request , wait for app Sweep code .
The user to use app Scanning code can be regarded as B: Scan code for authorization , Returns a temporary Token For secondary certification .
The user is in app Making a confirmation login can be seen as C: Confirm login , Authorized user at Web End login .
The backend will return a formal message after the user confirms the login Token It can be regarded as a step D.
The follow-up front-end is based on the formal Token Access the background interface , Officially in Web It can be regarded as E and F.
Reasons for secondary certification
The reason why the user needs to confirm login again after scanning the code , Instead of just logging in , For the sake of user safety , Avoid the user scanning the QR code that others need to log in , Log in directly without confirmation , Cause others to access our information without our knowledge .
Implementation steps
One 、 The user accesses the web side , Select scan code to login
When the user selects scanning code to log in , A QR code generation request will be sent to the backend , Backend generation UUID, And save to Redis( Fixed effective time ), The status is set to UNUSED( not used ) state , If Redis Cache expiration , Then for EXPIRE( Be overdue ) state , The front end generates a QR code according to the content returned by the back end , And set a timer , Every once in a while, according to the contents of the QR code UUID, Send a request back , Get the status of the QR code , Update the content displayed in the interface .
Generate QR code backend interface :
/** * Generate QR code content * * @return result */
@GetMapping("/generate")
public BaseResult generate() {
String code = IdUtil.simpleUUID();
redisCache.setCacheObject(code, CodeUtils.getUnusedCodeInfo(),
DEFAULT_QR_EXPIRE_SECONDS, TimeUnit.SECONDS);
return BaseResult.success(GENERATE_SUCCESS, code);
}
The front end gets the content , Generate qr code :
getToken() {
this.codeStatus = 'EMPTY'
this.tip = ' Getting login code , One moment please '
// Valid time 60 second
this.effectiveSeconds = 60
clearInterval(this.timer)
request({
method: 'get',
url: '/code/generate'
}).then((response) => {
// The request is successful , Set QR code content , And update the relevant information
this.code = `${
HOST}/code/scan?code=${
response.data}`
this.codeStatus = 'UNUSED'
this.tip = ' Please use your mobile phone to scan the code to log in '
this.timer = setInterval(this.getTokenInfo, 2000)
}).catch(() => {
this.getToken()
})
}
Back end interface that returns QR code status information :
/** * Get QR code status information * * @param code QR code * @return result */
@GetMapping("/info")
public BaseResult info(String code) {
CodeVO codeVO = redisCache.getCacheObject(code);
if (codeVO == null) {
return BaseResult.success(INVALID_CODE, StringUtils.EMPTY);
}
return BaseResult.success(GET_SUCCESS, codeVO);
}
The front end polls for QR code status :
getTokenInfo() {
this.effectiveSeconds--
// QR code expired
if (this.effectiveSeconds <= 0) {
this.codeStatus = 'EXPIRE'
this.tip = ' QR code has expired , Please refresh '
return
}
// Polling and querying QR code status
request({
method: 'get',
url: '/code/info',
params: {
code: this.code.substr(this.code.indexOf('=') + 1)
}
}).then(response => {
const codeVO = response.data
// QR code expired
if (!codeVO || !codeVO.codeStatus) {
this.codeStatus = 'EXPIRE'
this.tip = ' QR code has expired , Please refresh '
return
}
// The QR code status is login
if (codeVO.codeStatus === 'CONFIRMING') {
this.username = codeVO.username
this.avatar = codeVO.avatar
this.codeStatus = 'CONFIRMING'
this.tip = ' Scan code successfully , Please confirm on your mobile phone '
return
}
// The QR code status is confirm login
if (codeVO.codeStatus === 'CONFIRMED') {
clearInterval(this.timer)
const token = codeVO.token
store.commit('setToken', token)
this.$router.push('/home')
Message.success(' Login successful ')
return
}
})
}
Two 、 Use your mobile phone to scan the code , QR code status changes
When the user uses the mobile phone to scan the code ( Logged in and is correct app, Otherwise, scanning the code will jump to the customized promotional page ), The status of the QR code will be updated to CONFIRMING( To be confirmed ) state , And in Redis The newly added user name and avatar information in the cache are saved for the front end to use and display , In addition, the login information of the user will be returned ( The login address 、 browser 、 operating system ) to app Exhibition , At the same time, a temporary Token to app( Fixed effective time ).
Background processing during code scanning :
/** * Handle unused QR codes * * @param code QR code * @param token token * @return result */
private BaseResult handleUnusedQr(String code, String token) {
// check app End access passing token
boolean isLegal = JwtUtils.verify(token);
if (!isLegal) {
return BaseResult.error(AUTHENTICATION_FAILED);
}
// Save user name 、 Avatar information , For front end display
String username = JwtUtils.getUsername(token);
CodeVO codeVO = CodeUtils.getConfirmingCodeInfo(username, DEFAULT_AVATAR_URL);
redisCache.setCacheObject(code, codeVO, DEFAULT_QR_EXPIRE_SECONDS, TimeUnit.SECONDS);
// Return to the login address 、 browser 、 Operating system and a temporary token to app
String address = HttpUtils.getRealAddressByIp();
String browser = HttpUtils.getBrowserName();
String os = HttpUtils.getOsName();
String tmpToken = JwtUtils.sign(username);
// Will be temporary token As key , The user name is stored in redis in
redisCache.setCacheObject(tmpToken, username, DEFAULT_TEMP_TOKEN_EXPIRE_MINUTES, TimeUnit.MINUTES);
LoginInfoVO loginInfoVO = new LoginInfoVO(address, browser, os, tmpToken);
return BaseResult.success(SCAN_SUCCESS, loginInfoVO);
}
3、 ... and 、 Confirm login by mobile phone
When the user app Click confirm to log in , The generated temporary Token Send a request to update the status , The status of the QR code will be updated to CONFIRMED( Login confirmed ) state , At the same time, the back end will generate a formal Token Save in Redis in , The front end gets this when polling for update status Token, Then use this Token Log in .
The back-end process confirms the login code :
/** 1. Process QR code of unconfirmed status 2. 3. @param code QR code 4. @param token token 5. @return result */
private BaseResult handleConfirmingQr(String code, String token) {
// Use temporary token Get username , And from redis Delete temporary token
String username = redisCache.getCacheObject(token);
if (StringUtils.isBlank(username)) {
return BaseResult.error(AUTHENTICATION_FAILED);
}
redisCache.deleteObject(token);
// Generate a formal according to the user name token And keep it in redis For front-end use
String formalToken = JwtUtils.sign(username);
CodeVO codeVO = CodeUtils.getConfirmedCodeInfo(username, DEFAULT_AVATAR_URL, formalToken);
redisCache.setCacheObject(code, codeVO, DEFAULT_QR_EXPIRE_SECONDS, TimeUnit.SECONDS);
return BaseResult.success(CONFIRM_SUCCESS);
}
Effect demonstration


ps: Notes , Bosses do not spray , If there are defects, please point out ,3Q!
边栏推荐
- 【无标题】
- 【Go ~ 0到1 】 第二天 6月25 Switch语句,数组的声明与遍历
- Basic operation of PMP from applying for the exam to obtaining the certificate, a must see for understanding PMP
- Operating principle of Rogowski coil
- Build the first neural network with pytoch and optimize it
- Error: `brew cask` is no longer a `brew` command. Use `brew <command> --cask` instead.
- Webrtc advantages and module splitting
- 叠加阶梯图和线图及合并线图和针状图
- [learning notes] shortest path + spanning tree
- 罗氏线圈工作原理
猜你喜欢

Operating principle of Rogowski coil

Love analysis released the 2022 love analysis · it operation and maintenance manufacturer panorama report, and an Chao cloud was strongly selected!

使用transform:scale之后导致页面鼠标悬浮事件消失

【无标题】

webrtc优势与模块拆分

Solution: selenium common. exceptions. WebDriverException: Message: ‘chromedriver‘ execu

抖音服務器帶寬有多大,才能供上億人同時刷?

找合适的PMP机构只需2步搞定,一查二问

Discussion on the improvement and application of the prepayment system in the management of electricity charge and price

AI chief architect 8-aica-gao Xiang, in-depth understanding and practice of propeller 2.0
随机推荐
It only takes two steps to find the right PMP organization, one check and two questions
[learning notes] search
Trailing Zeroes (II)
[introduction to SQL in 10 days] day5+6 consolidated table
Tree
Superimposed ladder diagram and line diagram and merged line diagram and needle diagram
VMware Workstation related issues
Power data
[cloud native | kubernetes] in depth understanding of pod (VI)
Avframe Memory Management API
The Falling Leaves
Kubernetes notes and the latest k3s installation introduction
Common faults and solutions of Substation
小程序 :遍历list里面的某个数组的值,等同于 for=“list” list.comment里面的某一项
Not so Mobile
NPM clean cache
为什么函数模板没有偏特化?
TCP
Loss loss function
Basic operation of PMP from applying for the exam to obtaining the certificate, a must see for understanding PMP