我们去Libraries中,找到Java相关的JWT。
这里我们就是使用两种官方的JWT实现:
-
java-jwt
-
jjwt-root
=========================================================================================
第一步:导包,导依赖。
com.auth0
java-jwt
3.18.3
第二步:调用JWT。
-
jwt三部分组成:header.payload.signature。
-
需要我们配置的也就只有payload,通过withClaim来配置。
import java.util.Calendar;
import org.junit.Test;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator.Builder;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.InvalidClaimException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.sun.org.apache.bcel.internal.generic.ALOAD;
public class JavaJwtTest {
//hmac256摘要算法,跟md5类似,只是这个hmac256需要指定key,通常这个key叫做salt盐。
String key = “123456abc”;
/*
-
测试java-jwt生成token字符串
-
jwt三部分组成:
-
header.payload.signature
*/
@Test
public void testGenerateToken() {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, 60*5);
//claim英文直译:声明意思
Builder builder = JWT.create()
//withClaim中设定的就是payload的内容。
.withClaim(“userid”, 123)
.withClaim(“userName”, “itholmes”)
.withClaim(“url”, “https//www.itholmes.top”)
//设置过期时间
.withExpiresAt(calendar.getTime());
String token = builder.sign(Algorithm.HMAC256(key));
System.out.println(token);
}
//校验
@Test
public void testVerify() {
String token = “eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6Iml0aG9sbWVzIiwiZXhwIjoxNjQ2NzUxMTk3LCJ1c2VyaWQiOjEyMywidXJsIjoiaHR0cHMvL3d3dy5pdGhvbG1lcy50b3AifQ.e7y_9iO_jtVXo90qaq5H0aiUmg29I9XeJqAgUCDb1zo”;
JWTVerifier build = JWT.require(Algorithm.HMAC256(key)).build();
DecodedJWT verify = null;
try{
verify = build.verify(token);
System.out.println(verify);
}catch(TokenExpiredException e) {
System.out.println(“该token已经过期。”);
}catch (SignatureVerificationException e) {
System.out.println(“签名不一致”);
}catch (AlgorithmMismatchException e) {
System.out.println(“签名算法不匹配”);
}catch (InvalidClaimException e) {
System.out.println(“payload不可用”);
}catch (Exception e) {
System.out.println(“其他错误校验失败”);
}
System.out.println(verify);
if(verify!=null) {
//asInt()方法转换类型。
Integer userid = verify.getClaim(“userid”).asInt();
String userName = verify.getClaim(“userName”).asString();
String url = verify.getClaim(“url”).asString();
System.out.println();
}
}
}
=====================================================================================
第一步:同样导包导依赖。
io.jsonwebtoken
jjwt
0.9.1
第二步:Jwts调用。
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
public class JJwtTest {
String key=“123435abc”;
//通过jjwt生成token字符串
@Test
public void testGenerateToken() {
//过期时间
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, 60*5);
//创建payLoad的私有声明(根据特定的业务需要添加)
Map<String, Object> claims = new HashMap<String, Object>();
claims.put(“userid”,123);
claims.put(“userName”,“itholmes”);
claims.put(“url”,“https//www.itholmes.top”);
JwtBuilder builder = Jwts.builder()
//设置payLoad,传入的是map类型
.setClaims(claims)
//设置过期时间
.setExpiration(calendar.getTime())
//设置签名使用的签名算法和签名使用的秘钥
.signWith(SignatureAlgorithm.HS256, key);
String compact = builder.compact();
System.out.println(compact);
}
//校验token
@Test
public void testVerify() {
String token=“eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6Iml0aG9sbWVzIiwiZXhwIjoxNjQ2NzUyNjcxLCJ1c2VyaWQiOjEyMywidXJsIjoiaHR0cHMvL3d3dy5pdGhvbG1lcy50b3AifQ.6M9yg8iGutEgoYNv97n3GV5_o29iL2YXbrdpME_xtXc”;
Claims claims = Jwts.parser()
.setSigningKey(key)//设置签名秘钥
.parseClaimsJws(token).getBody();//设置需要解析的jwt
Integer userId = claims.get(“userid”,Integer.class);
String userName = claims.get(“userName”,String.class);
String url = claims.get(“url”,String.class);
System.out.println();
}
}
===================================================================================
package com.itholmes.utils;
import java.util.Calendar;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator.Builder;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.InvalidClaimException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itholmes.bean.User;
public class JwtUtil {
//jwt的key也就是salt盐
private static final String key = “www.itholmes.top”;
//生成token
public static String generateToken(User user) throws JsonProcessingException {
//使用jackson来生成json字符串方便存取
ObjectMapper jackson = new ObjectMapper();
String user_string = jackson.writeValueAsString(user);
//通过calendar设置过期时间
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR, 7);
//创建builder对象
Builder builder = JWT.create()
//设置payload内容
.withClaim(“userInfo”, user_string)
.withExpiresAt(calendar.getTime());
//生成token
String token = builder.sign(Algorithm.HMAC256(key));
return token;
}
//校验token
public static DecodedJWT verify(String tokenToVerity) {
DecodedJWT verify = null;
try{
verify = JWT
.require(Algorithm.HMAC256(key))
.build()
.verify(tokenToVerity);
}catch(TokenExpiredException e) {
e.printStackTrace();
System.out.println(“该token已经过期。”);
}catch (SignatureVerificationException e) {
e.printStackTrace();
System.out.println(“签名不一致”);
}catch (AlgorithmMismatchException e) {
e.printStackTrace();
System.out.println(“签名算法不匹配”);
}catch (InvalidClaimException e) {
e.printStackTrace();
System.out.println(“payload不可用”);
}catch (Exception e) {
e.printStackTrace();
System.out.println(“其他错误校验失败”);
}
return verify;
}
//将DecodedJWT中的信息解析出来进行比对
public static User parse(DecodedJWT decodeJWT) throws JsonMappingException, JsonProcessingException {
Claim claim = decodeJWT.getClaim(“userInfo”);
if(claim!=null) {
String userString = claim.asString();
ObjectMapper jackson = new ObjectMapper();
User user = jackson.readValue(userString, User.class);
return user;
}
return null;
}
}
=====================================================================================
前端存储有两种方式:
-
通过cookie来存储。
-
通过浏览器本地存储来存储。
=======================================================================================
前端存储token后,之后每次请求都携带这个token,用于让服务端校验。
如何携带token?
-
Authorization:授权,将jwt放到请求头里面。
-
请求参数里面,参数名字无所谓,一般的都叫做token。
一般我们通过请求头来操作。例如:设置一个Authorization请求头获取本地存储的token,放到里面;传到服务器进行验证。
token的使用一般我们都是进行前后端分离的情况下使用。
前端发送token的几种常用的方式:
-
对于同源的tomcat项目,一般我们使用cookie作为载体来携带token令牌发给服务器。
-
对于跨源的,cookie就没法实现了。只能手动的通过ajax的beforeSend参数来设置请求头,进而向后台发送token令牌信息。但是,当第一次访问该页面的http请求协议是没办法携带token令牌的。
-
在Vue中,可以通过特定的方式来实现第一次访问也可以携带token的。
对于ajax我们可以通过beforeSend参数的xhr对象来设定请求头。
=============================================================================
package com.itholmes.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
@WebFilter(“/*”)
public class CorsFilter implements Filter{
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//设置跨域问题。
HttpServletResponse resp = (HttpServletResponse)response;
resp.addHeader(“Access-Control-Allow-Origin”, “*”);
resp.addHeader(“Access-Control-Allow-Headers”, “*”);
resp.addHeader(“Access-Control-Allow-Methods”, “*”);
resp.addHeader(“Access-Control-Max-Age”, “3600”);
最后
分享一套我整理的面试干货,这份文档结合了我多年的面试官经验,站在面试官的角度来告诉你,面试官提的那些问题他最想听到你给他的回答是什么,分享出来帮助那些对前途感到迷茫的朋友。
面试经验技巧篇
- 经验技巧1 如何巧妙地回答面试官的问题
- 经验技巧2 如何回答技术性的问题
- 经验技巧3 如何回答非技术性问题
- 经验技巧4 如何回答快速估算类问题
- 经验技巧5 如何回答算法设计问题
- 经验技巧6 如何回答系统设计题
- 经验技巧7 如何解决求职中的时间冲突问题
- 经验技巧8 如果面试问题曾经遇见过,是否要告知面试官
- 经验技巧9 在被企业拒绝后是否可以再申请
- 经验技巧10 如何应对自己不会回答的问题
- 经验技巧11 如何应对面试官的“激将法”语言
- 经验技巧12 如何处理与面试官持不同观点这个问题
- 经验技巧13 什么是职场暗语
面试真题篇
- 真题详解1 某知名互联网下载服务提供商软件工程师笔试题
- 真题详解2 某知名社交平台软件工程师笔试题
- 真题详解3 某知名安全软件服务提供商软件工程师笔试题
- 真题详解4 某知名互联网金融企业软件工程师笔试题
- 真题详解5 某知名搜索引擎提供商软件工程师笔试题
- 真题详解6 某初创公司软件工程师笔试题
- 真题详解7 某知名游戏软件开发公司软件工程师笔试题
- 真题详解8 某知名电子商务公司软件工程师笔试题
- 真题详解9 某顶级生活消费类网站软件工程师笔试题
- 真题详解10 某知名门户网站软件工程师笔试题
- 真题详解11 某知名互联网金融企业软件工程师笔试题
- 真题详解12 国内某知名网络设备提供商软件工程师笔试题
- 真题详解13 国内某顶级手机制造商软件工程师笔试题
- 真题详解14 某顶级大数据综合服务提供商软件工程师笔试题
- 真题详解15 某著名社交类上市公司软件工程师笔试题
- 真题详解16 某知名互联网公司软件工程师笔试题
- 真题详解17 某知名网络安全公司校园招聘技术类笔试题
- 真题详解18 某知名互联网游戏公司校园招聘运维开发岗笔试题
资料整理不易,点个关注再走吧
果面试问题曾经遇见过,是否要告知面试官
- 经验技巧9 在被企业拒绝后是否可以再申请
- 经验技巧10 如何应对自己不会回答的问题
- 经验技巧11 如何应对面试官的“激将法”语言
- 经验技巧12 如何处理与面试官持不同观点这个问题
- 经验技巧13 什么是职场暗语
[外链图片转存中…(img-RRTMMReK-1718693065217)]
面试真题篇
- 真题详解1 某知名互联网下载服务提供商软件工程师笔试题
- 真题详解2 某知名社交平台软件工程师笔试题
- 真题详解3 某知名安全软件服务提供商软件工程师笔试题
- 真题详解4 某知名互联网金融企业软件工程师笔试题
- 真题详解5 某知名搜索引擎提供商软件工程师笔试题
- 真题详解6 某初创公司软件工程师笔试题
- 真题详解7 某知名游戏软件开发公司软件工程师笔试题
- 真题详解8 某知名电子商务公司软件工程师笔试题
- 真题详解9 某顶级生活消费类网站软件工程师笔试题
- 真题详解10 某知名门户网站软件工程师笔试题
- 真题详解11 某知名互联网金融企业软件工程师笔试题
- 真题详解12 国内某知名网络设备提供商软件工程师笔试题
- 真题详解13 国内某顶级手机制造商软件工程师笔试题
- 真题详解14 某顶级大数据综合服务提供商软件工程师笔试题
- 真题详解15 某著名社交类上市公司软件工程师笔试题
- 真题详解16 某知名互联网公司软件工程师笔试题
- 真题详解17 某知名网络安全公司校园招聘技术类笔试题
- 真题详解18 某知名互联网游戏公司校园招聘运维开发岗笔试题
[外链图片转存中…(img-YI0tbqFB-1718693065217)]
资料整理不易,点个关注再走吧