将JWT放到项目中作为一个参数被掉用发起者传过来作为接口调用的口令
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
编写Jwt服务:
package com.shengqian.demo.service;
public interface JwtService {
String getJwtsString(String ip);
}
package com.shengqian.demo.service.impl;
import com.shengqian.demo.JwtUserName;
import com.shengqian.demo.Util.JwtUser;
import com.shengqian.demo.Util.JwtUtil;
import com.shengqian.demo.service.JwtService;
import org.springframework.stereotype.Service;
import java.sql.Timestamp;
/**
* ClassName JwtServiceImpl
* Description TODO
* Auther chaoj
* Date 2018/12/17 16:18
* Version 1.0
**/
@Service
public class JwtServiceImpl implements JwtService {
@Override
public String getJwtsString(String ip) {
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
JwtUser user = new JwtUser.Builder(JwtUserName.ADMIN.getUsername(), timestamp)
.ip(ip)
.password(JwtUserName.ADMIN.getInfo()).build();
long ttlMillis = 30*60;
String jwt = JwtUtil.createJwt(ttlMillis, user);
return jwt;
}
}
再贴上JwtUser和JwtUtil的代码,分别是接口调用的使用者和Jwt生成的工具类
package com.shengqian.demo.Util;
import java.sql.Timestamp;
/**
* ClassName JwtUser
* Description TODO
* Auther chaoj
* Date 2018/12/17 10:30
* Version 1.0
**/
public class JwtUser {
private final String ip ;
private final String username ;
private final String password ;
private final Timestamp timestamp;
public static class Builder{
private String ip = "0.0.0.0";
private String username;
private String password = "";
private Timestamp timestamp ;
public Builder(String username, Timestamp timestamp){
this.username = username;
this.timestamp = timestamp;
}
public Builder ip(String val){
ip = val;
return this;
}
public Builder password(String val){
password = val;
return this;
}
public JwtUser build(){return new JwtUser(this);}
}
public JwtUser(Builder builder){
ip = builder.ip;
username = builder.username;
password = builder.password;
timestamp = builder.timestamp;
}
public String getPassword() {
return password;
}
public Timestamp getTimestamp() {
return timestamp;
}
public String getIp() {
return ip;
}
public String getUsername() {
return username;
}
}
//JwtUser 的构造器采用Builder模式,这样可以有效检查参数,同时也是《Effective Java》推荐的写法
package com.shengqian.demo.Util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* ClassName JwtUtil
* Description TODO
* Auther chaoj
* Date 2018/12/17 10:49
* Version 1.0
**/
public class JwtUtil {
public static String createJwt(long ttlMillis, JwtUser user){
/**
* @description TODO 创建jwt
* @author chaoj
* @date 2018/12/17 11:03
* @Param [ttlMillis, user]
* @return java.lang.String
* @version 1.0
**/
SignatureAlgorithm algorithm = SignatureAlgorithm.HS256;
long millis = System.currentTimeMillis();
Date date = new Date(millis);
Map<String, Object> claims = new HashMap<String, Object>();
claims.put("ip", user.getIp());
claims.put("username", user.getUsername());
claims.put("timestamp", user.getTimestamp());
String key = user.getPassword();
String subject = user.getUsername();
JwtBuilder jwtBuilder = Jwts.builder().signWith(algorithm, key)
.setClaims(claims)
.setId(UUID.randomUUID().toString())
.setIssuedAt(date)
.setSubject(subject);
if (ttlMillis > 0){
long millisExp = millis + ttlMillis;
Date expdete = new Date(millisExp);
jwtBuilder.setExpiration(expdete);
}
return jwtBuilder.compact();
}
public static Claims parseJwt(String token, JwtUser user){
/**
* @description TODO 解析
* @author chaoj
* @date 2018/12/17 11:07
* @Param [token, user]
* @return io.jsonwebtoken.Claims
* @version 1.0
**/
String key = user.getPassword();
Claims claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(token).getBody();
return claims;
}
public static Boolean isVerify(String token, JwtUser user){
String key = user.getPassword();
Claims claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(token).getBody();
if (claims.get("password").equals(user.getPassword())){
return true;
}
return false;
}
}
然后写控制器方法
@RequestMapping(value = Path.LOGIN, method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> userLogin(@RequestParam("phone") final String phone,
@RequestParam("password") final String password,
@RequestParam("ip") final String ip){
Map<String, Object> ans = new HashMap<>();
UserInfoDto dto = userInfoService.getUser(phone);
if (!dto.isRegister()){
dto.setPassword(password);
UserInfoDto dto1 = userInfoService.checkPassword(dto);
if (dto1.isVoladate()){
ans.put("code", 200);
ans.put("info", "成功");
ans.put("key", jwtService.getJwtsString(ip));
return ans;
}
}
ans.put("code", 400);
ans.put("info", "用户名或密码错误");
return ans;
}
如果登录成功,返回一个key,作为接口调用的令牌。在我的设计中,jwt将被存放在分布式缓存和本地LRU缓存中,每次请求过来,先判断当前服务器缓存中是否有这个key,如果没有,就去问redis就行了。下一部分我将做把redis集成到spring boot中。
返回demo
{
"code": 200,
"key": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJjaGFvamlsYWppIiwiaXAiOiI2MS4xODYuMTg1LjE4MCIsImV4cCI6MTU0NTAzNjQyOCwiaWF0IjoxNTQ1MDM2NDI2LCJqdGkiOiIxNTUzY2JmMC1jMDBiLTQxZmQtOTdiYy1jM2Q3ZTBhMDM2ZDQiLCJ1c2VybmFtZSI6ImNoYW9qaWxhamkiLCJ0aW1lc3RhbXAiOjE1NDUwMzY0MjY5MTd9.w-XmT9yy7JVVJQt6wIJLjcpVfhN0EVZvc-MpMLVwN58",
"info": "成功"
}