什么是会话技术?
Cookie
以登录为例,用户在浏览器中将账号密码输入并勾选自动登录,浏览器发送请求,请求头中设置Cookie:userName:'张三' ,password:'1234aa' ,若登录成功,服务器将这个cookie保存下来,后续用户登录,服务器向客户端(即浏览器)发送之前存储的用户cookie自动登录。
Session
底层还是用cookie,每个浏览器对应一个session,用户通过浏览器发送请求,请求头中携带sessionId来区分要访问哪个session
令牌技术jwt
令牌格式
前面两部分是基于Base64编码的,最后一部分是基于编码算法(这里是HS256)和密钥的
使用流程
以自动登录为例,用户输入账号密码后请求服务器进行登录,服务器查询数据库校验账号密码成功后生成令牌(token),并把token发给用户,浏览器要将这个令牌记录下来,后续发送请求时携带这个令牌。
后端人员需要做的事👇
编写生成token的方法,在请求响应成功后将token响应给服务端
1.导入依赖
<!-- token-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- 基于java,需要引入这个-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
2.写一个JwtUtil
public class JwtUtil {
private static final String secretKey="odpodpodp";//密钥 注意这个密钥不能太短
private static final int expireTime=3600*1000;//有效期为1小时 (单位:毫秒)
//生成token
public static String buildToken(int userId,String password){
HashMap<String, Object> map = new HashMap<>();
map.put("userId",userId);
map.put("password",password);
String token=Jwts.builder()
.addClaims(map)//载荷(payload 即要加密的json字符串) 不是setClaims!!
.signWith(SignatureAlgorithm.HS256,secretKey)//指定加密算法和密钥
.setExpiration(new Date(currentTimeMillis()+expireTime))//设置有效期为1h
.compact();//生成
return token;
}
//jwt校验
public static Claims parseJwt(String token){
Claims claims = (Claims) Jwts.parser()
.setSigningKey(secretKey)//指定密钥
.parse(token)
.getBody();//生成json格式的map
return claims;
}
}
前端人员需要做的事👇
浏览器可以把服务器响应的token以键值对的形式存储在localStorage中
后续发送请求时携带token到后端去解析
测试一下
控制器
@RestController
//登录注册模块控制器
@RequestMapping("login")
public class LoginController {
@PostMapping("/testToken")
public Result testToken(@RequestBody User user){
int userId = user.getUserId();
String password = user.getPassword();
if(true)//校验账号密码的逻辑
{
String token = JwtUtil.buildToken(userId, password);
System.out.println("token:"+token);
//测试一下解码token
System.out.println("解码token...");
System.out.println(JwtUtil.parseJwt(token));
return new Result(Code.RETURN_TOKEN_OK,"登录成功,返回token",token);
}
return new Result(Code.RETURN_TOKEN_FAIL,"登录失败,请验证账号密码",null);
}
}
用postman访问接口
控制台输出
exp是还有多久过期