jwt java 项目实例_我爱java系列之---【商城项目微服务鉴权代码实现(二)—JWT在项目中的应用案例】...

一、思路分析

50f73ffaf3a92d447ecaf97037a7fb55.png

1. 用户进入网关开始登陆,网关过滤器进行判断,如果是登录,则路由到后台管理微服务进行登录

2. 用户登录成功,后台管理微服务签发JWT TOKEN信息返回给用户

3. 用户再次进入网关开始访问,网关过滤器接收用户携带的TOKEN

4. 网关过滤器解析TOKEN ,判断是否有权限,如果有,则放行,如果没有则返回未认证错误

二、代码实现

1.系统微服务签发token

(1)在changgou_service_system中创建类: JwtUtil

/*** JWT工具类*/

public classJwtUtil {//有效期为

public static final Long JWT_TTL = 3600000L;//60 * 60 *1000 一个小时//设置秘钥明文

public static final String JWT_KEY = "itcast";/*** 创建token

*@paramid

*@paramsubject

*@paramttlMillis

*@return

*/

public staticString createJWT(String id, String subject, Long ttlMillis) {

SignatureAlgorithm signatureAlgorithm=SignatureAlgorithm.HS256;long nowMillis =System.currentTimeMillis();

Date now= newDate(nowMillis);if(ttlMillis==null){

ttlMillis=JwtUtil.JWT_TTL;

}long expMillis = nowMillis +ttlMillis;

Date expDate= newDate(expMillis);

SecretKey secretKey=generalKey();

JwtBuilder builder=Jwts.builder()

.setId(id)//唯一的ID

.setSubject(subject) //主题 可以是JSON数据

.setIssuer("admin") //签发者

.setIssuedAt(now) //签发时间

.signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥

.setExpiration(expDate);//设置过期时间

returnbuilder.compact();

}/*** 生成加密后的秘钥 secretKey

*@return

*/

public staticSecretKey generalKey() {byte[] encodedKey =Base64.getDecoder().decode(JwtUtil.JWT_KEY);

SecretKey key= new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");returnkey;

}

}

(2)修改AdminController的login方法, 用户登录成功 则 签发TOKEN

/*** 登录

*@paramadmin

*@return

*/@PostMapping("/login")publicResult login(@RequestBody Admin admin){boolean login =adminService.login(admin);if(login){ //如果验证成功

Map info = new HashMap<>();

info.put("username",admin.getLoginName());

String token= JwtUtil.createJWT(UUID.randomUUID().toString(), admin.getLoginName(), null);

info.put("token",token);return new Result(true, StatusCode.OK,"登录成功",info);

}else{return new Result(false,StatusCode.LOGINERROR,"用户名或密码错误");

}

}

使用postman 测试

0e9734fbdd08f6f4b9537eb5c66ff143.png

2.网关过滤器验证token

(1)在changgou_gateway_system网关系统添加依赖

io.jsonwebtoken

jjwt

0.9.0

(2)创建JWTUtil类

/*** jwt校验工具类*/

public classJwtUtil {//有效期为

public static final Long JWT_TTL = 3600000L;//60 * 60 *1000 一个小时//设置秘钥明文

public static final String JWT_KEY = "itcast";/*** 生成加密后的秘钥 secretKey

*

*@return

*/

public staticSecretKey generalKey() {byte[] encodedKey =Base64.getDecoder().decode(JwtUtil.JWT_KEY);

SecretKey key= new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");returnkey;

}/*** 解析

*

*@paramjwt

*@return*@throwsException*/

public static Claims parseJWT(String jwt) throwsException {

SecretKey secretKey=generalKey();returnJwts.parser()

.setSigningKey(secretKey)

.parseClaimsJws(jwt)

.getBody();

}

}

(3)创建过滤器,用于token验证

/*** 鉴权过滤器 验证token*/@Componentpublic class AuthorizeFilter implementsGlobalFilter, Ordered {private static final String AUTHORIZE_TOKEN = "token";

@Overridepublic Monofilter(ServerWebExchange exchange, GatewayFilterChain chain) {//1. 获取请求

ServerHttpRequest request =exchange.getRequest();//2. 则获取响应

ServerHttpResponse response =exchange.getResponse();//3. 如果是登录请求则放行

if (request.getURI().getPath().contains("/admin/login")) {returnchain.filter(exchange);

}//4. 获取请求头

HttpHeaders headers =request.getHeaders();//5. 请求头中获取令牌

String token =headers.getFirst(AUTHORIZE_TOKEN);//6. 判断请求头中是否有令牌

if(StringUtils.isEmpty(token)) {//7. 响应中放入返回的状态吗, 没有权限访问

response.setStatusCode(HttpStatus.UNAUTHORIZED);//8. 返回

returnresponse.setComplete();

}//9. 如果请求头中有令牌则解析令牌

try{

JwtUtil.parseJWT(token);

}catch(Exception e) {

e.printStackTrace();//10. 解析jwt令牌出错, 说明令牌过期或者伪造等不合法情况出现

response.setStatusCode(HttpStatus.UNAUTHORIZED);//11. 返回

returnresponse.setComplete();

}//12. 放行

returnchain.filter(exchange);

}

@Overridepublic intgetOrder() {return 0;

}

}

(4)测试:

注意: 数据库中管理员账户为 : admin , 密码为 : 123456

如果不携带token直接访问,则返回401错误

9386720074451792da9fc04929e24882.png

如果携带正确的token,则返回查询结果

c3779e20fa91765e16ff9d09099004b6.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值