一、JWT工具类
JWT的本质就是一个字符串
它是将用户信息保存到一个Json字符串中,然后进行编码后得到一个JWT token
package com.lin.commonutils;
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 linZT
* @date 2022-4-1 14:39
* JWT工具类
*/
public class JwtUtils {
/**
* 两个常量: 过期时间;秘钥
*/
public static final long EXPIRE = 1000*60*60*24;
public static final String SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";
/**
* 生成token字符串的方法
* @param id
* @param nickname
* @return
*/
public static String getJwtToken(String id,String nickname){
String JwtToken = Jwts.builder()
//JWT头信息
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS2256")
//设置分类;设置过期时间 一个当前时间,一个加上设置的过期时间常量
.setSubject("lin-user")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
//设置token主体信息,存储用户信息
.claim("id", id)
.claim("nickname", nickname)
//.signWith(SignatureAlgorithm.ES256, SECRET)
.signWith(SignatureAlgorithm.HS256, SECRET)
.compact();
return JwtToken;
}
/**
* 判断token是否存在与有效
* @Param jwtToken
*/
public static boolean checkToken(String jwtToken){
if (StringUtils.isEmpty(jwtToken)){
return false;
}
try{
//验证token
Jwts.parser().setSigningKey(SECRET).parseClaimsJws(jwtToken);
}catch (Exception e){
e.printStackTrace();
return false;
}
return true;
}
/**
* 判断token是否存在与有效
* @Param request
*/
public static boolean checkToken(HttpServletRequest request){
try {
String token = request.getHeader("token");
if (StringUtils.isEmpty(token)){
return false;
}
Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
}catch (Exception e){
e.printStackTrace();
return false;
}
return true;
}
/**
* 根据token获取会员id
* @Param request
*/
public static String getMemberIdByJwtToken(HttpServletRequest request){
String token = request.getHeader("token");
if (StringUtils.isEmpty(token)){
return "";
}
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
Claims body = claimsJws.getBody();
return (String) body.get("id");
}
}
二、利用token(令牌)进行用户身份验证的流程
- 客户端使用用户名和密码请求登录
- 服务端收到请求,验证用户名和密码
- 验证成功后,服务端会签发一个token,再把这个token返回给客户端
- 客户端收到token后可以把它存储起来,比如放到cookie中
- 客户端每次向服务端请求资源时需要携带服务端签发的token,可以在cookie或者header中携带
- 服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求数据
三 单点登录
单点登录3种方式:
四、JWT结构
JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)
。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串
用法
1、controller层
@Autowired
private UcenterMemberService memberService;
/**
* 登录并返回token
* 单点登录,返回token(使用jwt规则生成字符串)
* @param loginVo
* @return
*/
@ApiOperation(value = "登录并返回token")
@PostMapping("/login")
public Result login(@RequestBody LoginVo loginVo){
String token = memberService.login(loginVo);
return Result.ok().data("token",token);
}
2、service层
@Override
public String login(LoginVo loginVo) {
String mobile = loginVo.getMobile();
String password = loginVo.getPassword();
//校验参数
if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(password)){
throw new LinException(20001,"登录失败");
}
//获取用户
UcenterMember member = baseMapper.selectOne(new QueryWrapper<UcenterMember>().eq("mobile", mobile));
//用户不存在
if (member == null){
throw new LinException(20001,"用户不存在");
}
//用户存在,校验密码
//数据库的密码是加密的
//所以前端传进来的密码后端要自己先加密,再重新比对
if (!MD5.encrypt(password).equals(member.getPassword())){
throw new LinException(20001,"密码不正确");
}
//用户和密码都正常,看看是否被禁用
if (member.getIsDisabled()){
throw new LinException(20001,"被禁用");
}
//使用JWT生成token字符串,登录成功后返回
String jwtToken = JwtUtils.getJwtToken(member.getId(), member.getNickname());
return jwtToken;
}
相关文章
暂无评论...