spring cloud基于JWT的token认证实践
header里面放Authorization,Authorization里面放的就是token,就相当于每次发送请求的时候,拦截器都会拦截一次你的请求,把你请求头部的Authorization拿出来,与当前存在服务器上的token做对比
对比相同,拦截器就为你当前的请求放行,继续执行你的请求
如果不是同一个,那么服务器会截断你的请求并发送错误码给前端,让前端验证身份重新登陆。
post提交请求:http://192.168.10.25:5001/SINOTRANS-AUTH/auth/getTokenbyTerminal,获取token值,携带token进行验证。样例如下:
1.pom.xml引入jar
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
源码如下可借鉴:
JwtUtil.java
public class JwtUtil {
public static final long EXPIRATION_TIME = 3600_000_000L; // 1000 hour
public static final String SECRET = "sinotranszhanglongshandonglinyijunanxianggoujie";//please change to your own encryption secret.
public static final String TOKEN_PREFIX = "Bearer ";
public static String generateToken(String userId) {
HashMap<String, Object> map = new HashMap<>();
//you can put any data in the map
map.put("userId", userId);
String jwt = Jwts.builder()
.setClaims(map)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET)
.compact();
return TOKEN_PREFIX + jwt; //jwt前面一般都会加Bearer
}
public static String validateToken(String token) {
try {
// parse the token.
Map<String, Object> body = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token.replace("Bearer ",""))
.getBody();
String userId=body.get("userId").toString();
return userId;
}catch (Exception e){
throw new IllegalStateException("Invalid Token. "+e.getMessage());
}
}
}
3.AuthController.java
@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
SystemRemote systemRemote;
@Value("${server.port}")
String port;
/**
* 获取用户服务的端口
* @return
*/
@RequestMapping("/getAuthPort")
public String getAuthPort() {
return "auth-service port:" + port;
}
@RequestMapping(value="/getTokenbyTerminal", method = RequestMethod.POST)
@ResponseBody
@CrossOrigin
public String getTokenbyTerminal(@RequestBody Map<String, Object> map) {
String code="";
String secret="";
if(map.containsKey("code")){
code=map.get("code").toString();
System.out.print("code");
}
if(map.containsKey("secret")){
secret=map.get("secret").toString();
System.out.print("secret");
}
Terminal terminal= systemRemote.getTokenbySecret(code,secret);
JsonResult jsonResult=new JsonResult();
String token="";
if(terminal!=null){
token=JwtUtil.generateToken(terminal.getId());
jsonResult.setSuccess(true);
}else{
jsonResult.setSuccess(false);
}
jsonResult.setData(token);
token= JSON.toJSON(jsonResult).toString();
return token;
}
}
SystemRemote.java
@FeignClient(value = "sinotrans-system", fallback = SystemRemoteHystrix.class)
public interface SystemRemote {
@RequestMapping (value = "/terminal/getTokenbySecret", method = RequestMethod.POST)
Terminal getTokenbySecret(@RequestParam("code") String code, @RequestParam("secret") String secret);
}
SystemRemoteHystrix.java
@Component
public class SystemRemoteHystrix implements SystemRemote {
private Logger logger= LoggerFactory.getLogger(this.getClass());
@Override
public Terminal getTokenbySecret(String code, String password) {
return null;
}
}
Terminal.java
//终端
@Data
public class Terminal implements Serializable {
private String id;
private String code;
private String name;
//秘钥
private String secret;
//作用域
private String sscope;
private String remark;
//有效期时间
private Date endDate;
//终端状态
private String status;
private Date createTime;
private Date updateTime;
}
TerminalController.java
@RestController
@RequestMapping("/terminal")
public class TerminalController {
@Autowired
private TerminalService terminalService;
@RequestMapping(value="/getTokenbySecret", method = RequestMethod.POST)
@CrossOrigin
public Terminal getTokenbySecret(@RequestParam("code") String code, @RequestParam("secret") String secret) {
Terminal terminal= terminalService.getTokenbySecret(code,secret);
return terminal;
}
}
TerminalService.java
/**
*
*/
public interface TerminalService {
//根据秘钥和终端编码获取token
Terminal getTokenbySecret(String code, String secret);
}
TerminalServiceImpl.java
/**
*
*/
@Service(value = "terminalService")
public class TerminalServiceImpl implements TerminalService {
@Autowired
private TerminalMapper terminalMapper;//这里会报错,但是并不会影响
@Override
public Terminal getTokenbySecret(String code, String secret) {
Terminal terminal= terminalMapper.getTokenbySecret(code,secret);
return terminal;
}
}
TerminalMapper.java
public interface TerminalMapper extends BaseMapper<Terminal> {
//根据秘钥和终端编码获取token
Terminal getTokenbySecret(@Param("code")String code, @Param("secret")String secret);
}
TerminalMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sinotrans.system.mapper.TerminalMapper" >
<select id="getTokenbySecret" resultType="com.sinotrans.common.model.Terminal">
SELECT
t.id AS id,
t.code AS code,
t.name AS name,
t.sscope AS sscope,
t.status AS status,
t.secret AS secret,
t.remark AS remark
FROM
terminal t
WHERE
t.code= #{code}
AND t.secret = #{secret}
</select>
</mapper>