当前位置:网站首页>Day112. Shangyitong: Mobile verification code login function
Day112. Shangyitong: Mobile verification code login function
2022-07-28 08:38:00 【Fireworks youth·】
Catalog
One 、 Mobile phone verification code interface implementation
1、 stay service Create service_user modular
2、 Implement login and registration interface
One 、 Mobile verification code login generation token
Two 、 apply 、 Integrate Alibaba cloud SMS service , Build the interface
3、 ... and 、 Complete the login interface
Four 、 Front page implementation
One 、 Mobile phone verification code interface implementation
1、 stay service Create service_user modular
See courseware for details

2、 Implement login and registration interface
1. Analysis interface
* Parameters :LoginVo, request
* Return value :map( Sign in 、 user name )

2. controller
@Api(tags = " The user interface ")
@RestController
@RequestMapping("/api/user")
public class UserInfoApiController {
@Autowired
private UserInfoService userInfoService;
@ApiOperation(value = " Member login ")
@PostMapping("login")
public R login(@RequestBody LoginVo loginVo, HttpServletRequest request) {
loginVo.setIp(IpUtils.getIpAddr(request));
Map<String, Object> map = userInfoService.login(loginVo);
return R.ok().data(map);
}
}3. service
@Service
public class UserInfoServiceImpl extends
ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
// Member login
@Override
public Map<String, Object> login(LoginVo loginVo) {
//1. data verification
String phone = loginVo.getPhone();
String code = loginVo.getCode();
if(StringUtils.isEmpty(phone)||StringUtils.isEmpty(code)){
throw new YyghException(20001," Incorrect registration information ");
}
//2. TODO Verification code
//3. Query user information according to mobile phone number
QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
wrapper.eq("phone",phone);
UserInfo userInfo = baseMapper.selectOne(wrapper);
//4. User information is empty , Go to the registration function
if(userInfo==null){
userInfo = new UserInfo();
userInfo.setPhone(phone);
userInfo.setStatus(1); //0 lock 1 normal
baseMapper.insert(userInfo);
}
//5. Determine if the user is locked
if(userInfo.getStatus()==0){
throw new YyghException(20001," The user is locked ");
}
//6. Complete user information
// Return to the page display name
Map<String, Object> map = new HashMap<>();
String name = userInfo.getName();
if(StringUtils.isEmpty(name)) {
name = userInfo.getNickName();
}
if(StringUtils.isEmpty(name)) {
name = userInfo.getPhone();
}
//7. TODO The user login
map.put("token", "");
map.put("name", name);
return map;
}
}One 、 Mobile verification code login generation token
1、 Single sign on solution :
1.Session radio broadcast ( Broadcast storm 、 Waste bandwidth )
2.Redis+cookie
3. token+cookie
2、JWT Tools :
JWT(Json Web Token) Is a kind of implementation based on the JSON Open standards for .
JWT The declaration of is generally used to pass the authenticated user identity information between the identity provider and the service provider , To get resources from the resource server . For example, it's used in user login
JWT The most important function is to token The information of Anti-counterfeiting effect .
principle : One JWT from Three parts : Common part 、 Private sector 、 Signature part . Finally, the combination of the three base64 Code to get JWT.
3、 Realization JWP Integrate
1. common_utils Modules add dependencies
<!--JWP-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>2. add to JWT Tool class
public class JwtHelper {
private static long tokenExpiration = 24*60*60*1000;
private static String tokenSignKey = "123456";
public static String createToken(Long userId, String userName) {
String token = Jwts.builder()
.setSubject("YYGH-USER")
.setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
.claim("userId", userId)
.claim("userName", userName)
.signWith(SignatureAlgorithm.HS512, tokenSignKey)
.compressWith(CompressionCodecs.GZIP)
.compact();
return token;
}
public static Long getUserId(String token) {
if(StringUtils.isEmpty(token)) return null;
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
Claims claims = claimsJws.getBody();
Integer userId = (Integer)claims.get("userId");
return userId.longValue();
}
public static String getUserName(String token) {
if(StringUtils.isEmpty(token)) return "";
Jws<Claims> claimsJws
= Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
Claims claims = claimsJws.getBody();
return (String)claims.get("userName");
}
public static void main(String[] args) {
String token = JwtHelper.createToken(1L, "55");
System.out.println(token);
System.out.println(JwtHelper.getUserId(token));
System.out.println(JwtHelper.getUserName(token));
}
}3. perfect service Method , Realize the interface function 、
// Member login
@Override
public Map<String, Object> login(LoginVo loginVo) {
...
//7. TODO The user login
String token = JwtHelper.createToken(userInfo.getId(), userInfo.getName());
map.put("token", token);
map.put("name", name);
return map;Two 、 apply 、 Integrate Alibaba cloud SMS service , Build the interface
Official documents :Java SDK - SMS service - Alibaba cloud
1. Open Dingxin SMS service Dingxin ( Reference courseware )
Need to apply for signature 、 Templates


2. stay service Create sub modules under modules service_msm

Import dependence :
<dependencies>
<!-- Ali json Tools -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!-- Alibaba cloud core package -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
</dependency>
</dependencies>application.properties
# Service port
server.port=8204
# service name
spring.application.name=service-msm
spring.redis.host=192.168.86.86
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
# Maximum blocking waiting time ( A negative number means no limit )
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
# Minimum free time
# return json The global time format of
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
# nacos Service address
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848Add gateway configuration
# Set the routing id
spring.cloud.gateway.routes[3].id=service-msm
# To set up a route uri
spring.cloud.gateway.routes[3].uri=lb://service-msm
# Set route assertion , agent servicerId by auth-service Of /auth/ route
spring.cloud.gateway.routes[3].predicates= Path=/*/msm/**3. Realization controller
@Api(description = " Send verification code ")
@RestController
@RequestMapping("/api/msm")
public class MsmController {
@Autowired
private MsmService msmService;
@Autowired
private RedisTemplate<String,String> redisTemplate;
@ApiOperation(value = " Send verification code message ")
@GetMapping(value = "/send/{phone}")
public R send(@PathVariable String phone) {
//1. According to the mobile phone number redis, Get the verification code for verification
String redisCode = redisTemplate.opsForValue().get(phone);
if(redisCode!=null){
return R.ok();
}
//2. Get a new verification code , Package verification code
String code = RandomUtil.getFourBitRandom();
Map<String,String> paramMap = new HashMap<>();
paramMap.put("code",code);
//3. Call the interface to send SMS
boolean isSend = msmService.send(phone,paramMap);
//4. Store the verification code in Redis, Five minutes
if(isSend){
redisTemplate.opsForValue().set(phone,code,5, TimeUnit.MINUTES);
return R.ok();
}else {
return R.error().message(" Failed to send SMS ");
}
}
}4. service
@Service
public class MsmServiceImpl implements MsmService {
// Send verification code message
@Override
public boolean send(String phone, Map<String, String> paramMap) {
//1. Check the cell phone number
if(StringUtils.isEmpty(phone)){
return false;
}
//3. Create a request object to store parameters AccessKey id、 Secret key
DefaultProfile profile =
DefaultProfile.getProfile("default", "LTAI5tMGtK....", "baAdNzxAjnIMKU3....");
IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
//request.setProtocol(ProtocolType.HTTPS);
request.setMethod(MethodType.POST);
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2017-05-25");
request.setAction("SendSms");
request.putQueryParameter("PhoneNumbers", phone);
// Be the same as the signature of the application
request.putQueryParameter("SignName", " My grain online education website ");
request.putQueryParameter("TemplateCode", "SMS_183195440");
request.putQueryParameter("TemplateParam", JSONObject.toJSONString(paramMap));
try {
//4. Send the request using the client object method , Get a response
CommonResponse response = client.getCommonResponse(request);
//5. Get the final result from the response
System.out.println(response.getData());
return response.getHttpResponse().isSuccess();
} catch (ClientException e) {
e.printStackTrace();
throw new YyghException(20001," SMS sending failed ");
}
}
}3、 ... and 、 Complete the login interface
1. Import redis To configure
#redis
spring.redis.host=192.168.86.86
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
# Maximum blocking waiting time ( A negative number means no limit )
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=02. modify service Method
@Autowired
RedisTemplate<String, String> redisTemplate;
// Member login
@Override
public Map<String, Object> login(LoginVo loginVo) {
//1. data verification
String phone = loginVo.getPhone();
String code = loginVo.getCode();
if(StringUtils.isEmpty(phone)||StringUtils.isEmpty(code)){
throw new YyghException(20001," Incorrect registration information ");
}
//2. TODO Verification code
//2.1 From... According to the mobile phone number redis Take out the verification code
String rediscode = redisTemplate.opsForValue().get(phone);
//2.2 Comparison verification code
//2.2 Comparison verification code , Note the string null pointer
if(!code.equals(rediscode)){
throw new YyghException(20001," The verification code is wrong ");
}
//3. Query user information according to mobile phone number
QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
wrapper.eq("phone",phone);
UserInfo userInfo = baseMapper.selectOne(wrapper);
//4. User information is empty , Go to the registration function
if(userInfo==null){
userInfo = new UserInfo();
userInfo.setPhone(phone);
userInfo.setStatus(1); //0 lock 1 normal
baseMapper.insert(userInfo);
}
//5. Determine if the user is locked
if(userInfo.getStatus()==0){
throw new YyghException(20001," The user is locked ");
}
//6. Complete user information
// Return to the page display name
Map<String, Object> map = new HashMap<>();
String name = userInfo.getName();
if(StringUtils.isEmpty(name)) {
name = userInfo.getNickName();
}
if(StringUtils.isEmpty(name)) {
name = userInfo.getPhone();
}
//7. TODO The user login
String token = JwtHelper.createToken(userInfo.getId(), userInfo.getName());
map.put("token", token);
map.put("name", name);
return map;
}Four 、 Front page implementation
1. establish API Interface method
userinfo.js
import request from '@/utils/request'
const api_name = `/api/user`
export default {
// validate logon
login(userInfo) {
return request({
url: `${api_name}/login`,
method: `post`,
data: userInfo
})
}
}msm.js
import request from '@/utils/request'
const api_name = `/api/msm`
export default {
// Send verification message
sendCode(mobile) {
return request({
url: `${api_name}/send/${mobile}`,
method: `get`
})
}
}2. modify layouts/myheader.vue
<template>
<div class="header-container">
<div class="wrapper">
<!-- logo -->
<div class="left-wrapper v-link selected">
<img style="width: 50px" width="50" height="50" src="~assets/images/logo.png">
<span class="text"> Shang Yitong Unified reservation and registration platform </span>
</div>
<!-- Search box -->
<div class="search-wrapper">
<div class="hospital-search animation-show">
<el-autocomplete class="search-input small" prefix-icon="el-icon-search" v-model="state"
:fetch-suggestions="querySearchAsync" placeholder=" Click to enter the name of the hospital " @select="handleSelect">
<span slot="suffix" class="search-btn v-link highlight clickable selected"> Search for </span>
</el-autocomplete>
</div>
</div>
<!-- On the right side -->
<!-- On the right side -->
<div class="right-wrapper">
<span class="v-link clickable"> Help center </span>
<span v-if="name == ''" class="v-link clickable" @click="showLogin()" id="loginDialog"> Sign in / register </span>
<el-dropdown v-if="name != ''" @command="loginMenu">
<span class="el-dropdown-link">
{
{ name }}<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu class="user-name-wrapper" slot="dropdown">
<el-dropdown-item command="/user"> Real name authentication </el-dropdown-item>
<el-dropdown-item command="/order"> Registered order </el-dropdown-item>
<el-dropdown-item command="/patient"> Patient management </el-dropdown-item>
<el-dropdown-item command="/logout" divided> Log out </el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
<!-- Login pop-up layer -->
<el-dialog :visible.sync="dialogUserFormVisible" style="text-align: left;" top="50px" :append-to-body="true"
width="960px" @close="closeDialog()">
<div class="container">
<!-- Mobile phone login #start -->
<div class="operate-view" v-if="dialogAtrr.showLoginType === 'phone'">
<div class="wrapper" style="width: 100%">
<div class="mobile-wrapper" style="position: static;width: 70%">
<span class="title">{
{ dialogAtrr.labelTips }}</span>
<el-form>
<el-form-item>
<el-input v-model="dialogAtrr.inputValue" :placeholder="dialogAtrr.placeholder"
:maxlength="dialogAtrr.maxlength" class="input v-input">
<span slot="suffix" class="sendText v-link" v-if="dialogAtrr.second > 0">{
{
dialogAtrr.second }}s </span>
<span slot="suffix" class="sendText v-link highlight clickable selected"
v-if="dialogAtrr.second == 0" @click="getCodeFun()"> To resend </span>
</el-input>
</el-form-item>
</el-form>
<!-- Send verification code or login dynamic -->
<div class="send-button v-button" @click="btnClick()"> {
{ dialogAtrr.loginBtn }}</div>
</div>
<div class="bottom">
<div class="wechat-wrapper" @click="weixinLogin()"><span class="iconfont icon"></span>
</div>
<span class="third-text"> Third party account login </span>
</div>
</div>
</div>
<!-- Mobile phone login #end -->
<!-- Wechat login #start -->
<div class="operate-view" v-if="dialogAtrr.showLoginType === 'weixin'">
<div class="wrapper wechat" style="height: 400px">
<div>
<div id="weixinLogin"></div>
</div>
<div class="bottom wechat" style="margin-top: -80px;">
<div class="phone-container">
<div class="phone-wrapper" @click="phoneLogin()"><span class="iconfont icon"></span>
</div>
<span class="third-text"> SMS verification code login </span>
</div>
</div>
</div>
</div>
<!-- Wechat login #end -->
<div class="info-wrapper">
<div class="code-wrapper">
<div><img src="//img.114yygh.com/static/web/code_login_wechat.png" class="code-img">
<div class="code-text"><span class="iconfont icon"></span> Wechat scanning and attention
</div>
<div class="code-text"> “ Quick appointment registration ”</div>
</div>
<div class="wechat-code-wrapper"><img src="//img.114yygh.com/static/web/code_app.png"
class="code-img">
<span class="iconfont icon"></span><div class="code-text"> Scan and download </div>
<div class="code-text"> “ Make an appointment for registration ”APP</div>
</div>
</div>
<div class="slogan">
<div>xxxxxx Officially designated platform </div>
<div> Fast registration Be safe </div>
</div>
</div>
</div>
</el-dialog>
</div>
</template>3. JS Realization
<script>
import cookie from 'js-cookie'
import Vue from 'vue'
import userInfoApi from '@/api/userinfo'
import msmApi from '@/api/msm'
import hospitalApi from '@/api/hospital'
// Constant , Default initialization value
const defaultDialogAtrr = {
showLoginType: 'phone', // Control the switching between mobile login and wechat login
labelTips: ' Phone number ', // Input box prompt
inputValue: '', // Input box binding object
placeholder: ' Please input your mobile number ', // Input box placeholder
maxlength: 11, // Input box length control
loginBtn: ' Get verification code ', // Login button or get verification code button text
sending: true, // Whether the verification code can be sent
second: -1, // Countdown time second>0 : Show countdown second=0 : To resend second=-1 : Show nothing
clearSmsTime: null // Countdown timer task reference Close the login layer and clear the scheduled task
}
export default {
data() {
return {
userInfo: { // Login object
openid: "",
phone: "",
code: ""
},
dialogAtrr: defaultDialogAtrr, // Pop up layer objects
dialogUserFormVisible: false, // Whether the pop-up layer is displayed
name: "" // User name after login
}
},
created() {
// Determine if the user has logged in
this.showInfo()
},
methods: {
// Open the login registration pop-up layer
showLogin() {
this.dialogUserFormVisible = true
this.dialogAtrr = { ...defaultDialogAtrr } // Object storage operators , Open up new memory space
},
// Send verification code or login
btnClick() {
if (this.dialogAtrr.loginBtn == " Get verification code ") {
// Assign a value to the mobile number
this.userInfo.phone = this.dialogAtrr.inputValue
// Call the send verification code method
this.getCodeFun();
} else {
// Call the login method
this.login();
}
},
// Send verification code
getCodeFun() {
//1. Check cell phone number
if (!(/^1[34578]\d{9}$/.test(this.userInfo.phone))) {
this.$message.error(" The mobile number is incorrect ")
return;
}
//2. Change the pop-up layer object value to login
this.dialogAtrr.inputValue = ''
this.dialogAtrr.placeholder = ' Please enter the verification code '
this.dialogAtrr.maxlength = 6
this.dialogAtrr.loginBtn = ' Login immediately '
//3. Determine whether to send the verification code repeatedly sending
if (!this.dialogAtrr.sending) {
this.$message.error(" Please do not send repeatedly ")
return;
}
this.dialogAtrr.sending = false
//4. Send verification code
msmApi.sendCode(this.userInfo.phone)
.then(response => {
// Countdown method
this.timeDown();
})
.catch(e => {
//5. Send failed back before interface
this.$message.error(" Sending verification code failed ")
this.showLogin()
})
},
timeDown() {
if (this.clearSmsTime) {
clearInterval(this.clearSmsTime);
}
this.dialogAtrr.second = 60;
this.dialogAtrr.labelTips = ' The captcha has been sent to ' + this.userInfo.phone
this.clearSmsTime = setInterval(() => {
--this.dialogAtrr.second;
if (this.dialogAtrr.second < 1) {
// Clear timer , You need to be in pairs
clearInterval(this.clearSmsTime);
this.dialogAtrr.sending = true;
this.dialogAtrr.second = 0;
}
}, 1000);
},
// Login method
login() {
//1. Assign a value to the verification code
this.userInfo.code = this.dialogAtrr.inputValue
//2. Verify the validity of parameters
if (this.dialogAtrr.loginBtn == ' Submitting ...') {
this.$message.error(' Repeated submission ')
return;
}
if (this.userInfo.code == '') {
this.$message.error(' Verification code must be entered ')
return;
}
if (this.userInfo.code.length != 4) {
this.$message.error(' The format of the verification code is incorrect ')
return;
}
this.dialogAtrr.loginBtn = ' Submitting ...'
//3. Submit login information , Successfully set login status (name,cookie)
userInfoApi.login(this.userInfo)
.then(response => {
// Set login status
this.setCookies(response.data.name, response.data.token)
})
.catch(e => {
//4. Fail back
this.dialogAtrr.loginBtn = ' Log in right now '
})
},
// Set login status
setCookies(name, token) {
//domain: Scope of action
cookie.set("name", name, { domain: 'localhost' })
cookie.set("token", token, { domain: 'localhost' })
window.location.reload()
},
// Determine if you are logged in
showInfo() {
let token = cookie.get("token")
if (token) {
this.name = cookie.get("name")
console.log(this.name);
}
},
// Menu method Log out ?
loginMenu(command) {
if ('/logout' == command) {
cookie.set('name', '', { domain: 'localhost' })
cookie.set('token', '', { domain: 'localhost' })
// Jump to the page
window.location.href = '/'
} else {
window.location.href = command
}
},
handleSelect(item) {
window.location.href = '/hospital/' + item.hoscode
},
// Switch wechat login
weixinLogin() {
this.dialogAtrr.showLoginType = 'weixin'
},
// Switch mobile login
phoneLogin() {
this.dialogAtrr.showLoginType = 'phone'
this.showLogin()
}
}
};
</script>4. test 

边栏推荐
- 单片机IO口控制12V电压通断,MOS和三极管电路
- 2022牛客多校第二场解题报告
- opencv+paddle orc 识别图片提取表格信息
- Gbase appears in Unicom cloud Tour (Sichuan Station) to professionally empower cloud ecology
- 网络安全漏洞分析与漏洞复现
- Window 2 - > toolbar (28-1)
- classLoader加载的class的回收
- 中标捷报!南大通用GBase 8s中标南瑞集团2022年数据库框架项目
- Can‘t connect to server on ‘IP‘ (60)
- How CI framework integrates Smarty templates
猜你喜欢

阿里巴巴内部面试资料

Understand CDN

See how Google uses pre training weights in target detection tasks | CVPR 2022

Prescan quick start to master the road elements of lecture 15

一键开关机电路

MySQL how to add users and set permissions?

HCIP---LDP和MPLS技术(详解)

业务数字化飞速奔跑,管理数字化亟待出发

Starfish Os打造的元宇宙生态,跟MetaBell的合作只是开始

EMC EMI磁珠的特性
随机推荐
Prescan quick start to proficient in lecture 17, speed curve editor
HCIP---LDP和MPLS技术(详解)
PHPUnit在Window下如何配置
Machine learning how to achieve epidemic visualization -- epidemic data analysis and prediction practice
半桥BUCK电路—记录篇
PHP基础知识 - PHP 使用 MySQLI
PMP practice once a day | don't get lost in the exam -7.13
Understand the propagation process of EMI electromagnetic interference through five diagrams - the influence of square wave steepness on high-frequency components, the spectrum graph from time sequenc
UE4 engine customizes screenpass and MRT output
博客搭建七:hugo
CI框架如何集成Smarty模板
uniapp的swiper动态设置current值不生效解决办法
ASP. Net core foundation V
[mindspire YiDianTong robot-01] you may have seen many Knowledge Q & A robots, but this is a little different
leetcode/排序数组中两个数字之和
Gbase 8A MPP and Galaxy Kirin (x86 version) complete deep adaptation
2018年1月西邻雪山自驾游攻略
Unity中队列(Queue)的简单使用
2022牛客多校第二场解题报告
QT 怎么删除布局里的所有控件?