任务:
-
实现登录模块
(1)前端页面
(2)后端接口 -
实现注册模块
(1)前端
(2)整合JWT
(3)整合阿里云短信微服务
1.单点登录SSO
1.1 概述
登录系统后,登录该系统相关的其他互信系统,直接自动登录。用基于cookie的session实现登录不能实现在多个系统间登录。
1.2 SSO的实现方式
1. 广播方式
在一个模块登录后,该模块将用户登录的session复制到其他模块。用户登录其他模块时,直接登录。
缺点:浪费空间;如果模块多,会产生大量复制,浪费时间。
2. cookie + Redis 实现
3. Token(令牌)实现
Token:字符串,按照一定规则生成,字符串里面可以包含用户信息。
JWT:
手机验证码后台接口实现
-
创建子模块service_msm
-
创建service,controller
-
common引入依赖
-
配置类
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* @author
*/
public class JwtUtils {
public static final long EXPIRE = 1000 * 60 * 60 * 24;
public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";
public static String getJwtToken(String id, String nickname){
String JwtToken = Jwts.builder()
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
.setSubject("guli-user")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
.claim("id", id)
.claim("nickname", nickname)
.signWith(SignatureAlgorithm.HS256, APP_SECRET)
.compact();
return JwtToken;
}
/**
* 判断token是否存在与有效
* @param jwtToken
* @return
*/
public static boolean checkToken(String jwtToken) {
if(StringUtils.isEmpty(jwtToken)) return false;
try {
Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 判断token是否存在与有效
* @param request
* @return
*/
public static boolean checkToken(HttpServletRequest request) {
try {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) return false;
Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 根据token获取会员id
* @param request
* @return
*/
public static String getMemberIdByJwtToken(HttpServletRequest request) {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) return "";
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
Claims claims = claimsJws.getBody();
return (String)claims.get("id");
}
}
- 开通阿里云短信服务
- Controller,Service编写
验证码存入Redis中,可以设置过期时间。
注册接口
Controller:
Service:
package com.atguigu.educenter.service.impl;
import com.atguigu.commonutils.JwtUtils;
import com.atguigu.educenter.entity.UcenterMember;
import com.atguigu.educenter.mapper.UcenterMemberMapper;
import com.atguigu.educenter.service.UcenterMemberService;
import com.atguigu.servicebase.exceptionhandler.GuliException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/**
* <p>
* 会员表 服务实现类
* </p>
*
* @author xjtu5418
* @since 2020-07-29
*/
@Service
public class UcenterMemberServiceImpl extends ServiceImpl<UcenterMemberMapper, UcenterMember> implements UcenterMemberService {
//登录方法
//判断用户名,密码,手机号是否禁用
@Override
public String login(UcenterMember member) {
String mobile = member.getMobile();
String password = member.getPassword();
//1. 判断是否为空
if(StringUtils.isEmpty(mobile) || StringUtils.isEmpty(password))throw new GuliException(20001, "登录失败!");
//2. 判断手机号是否正确:从db中查询
QueryWrapper<UcenterMember> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mobile", mobile);
UcenterMember mobileMember = baseMapper.selectOne(queryWrapper);
//判断查询出来的对象是否为空
if(mobileMember == null){
throw new GuliException(20001, "登录失败!");
}
//3. 密码不同
if(password.equals(mobileMember.getPassword())){
throw new GuliException(20001, "登录失败!");
}
//4.手机号是否被禁用
if(mobileMember.getIsDisabled()){
throw new GuliException(20001, "登录失败!");
}
//到这里,用户登录密码都正确,登录成功------要返回token值----->要用到JWT工具类
//生成token字符串,使用JWT工具类
String token = JwtUtils.getJwtToken(mobileMember.getId(), mobileMember.getNickname());
return token;
}
}
重要代码:
BUG:
测试:
出现错误:
根据提示,进行排查请求体,看到请求方式出错。
测试:
- 创建实体类,用于封装注册数据,包含验证码属性;(实体类中不包含验证码,所以重新创建一个类,把验证码加上);
- Controller添加注册方法
Service:
测试:
根据id获取用户信息
前台页面
(完)