使用token和SpringMVC来实现安全的RESTFul接口

来源:互联网 发布:淘宝电热水龙头 编辑:程序博客网 时间:2024/05/18 01:02

首先写一个Controller,专门用于获取token的

@Autowired
private UserService userService;

@RequestMapping(value = "/token", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<TokenResult> queryUserById(@RequestBody User user) {//TokenResult包括Token和Message两个属性
try {
Token token = userService.getToken(user); //Token 包括String token和Date create两个属性
TokenResult tokenResult = new TokenResult();
if (null == token) {
tokenResult.setMessage("User authenticate failed.");
// 401
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(tokenResult);
}
tokenResult.setToken(token);
tokenResult.setMessage("User authenticate successful.");
// 创建
return ResponseEntity.status(HttpStatus.CREATED).body(tokenResult);
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}

UserService类中

public Token getToken(User user) {
// 每次生成会顶掉前面的token
if ("admin".equals(user.getName()) && "123456".equals(user.getPassword())) {//举个例子
Token token = new Token();
token.setCreate(new Date());
token.setToken(UUID.randomUUID().toString());
TokenManager.userOfToken.put("admin", token);//TokenManager.userOfToken是一个ConcurrentHashMap
return token;
}
return null;
}

然后写获取资源的Controller。这里使用@ModelAttribute注解,它所在的Controller每次在进入requestmapping后会先调用@ModelAttribute所在的方法

这个方法就是校验token的

@Autowired
private UserService userService;

@ModelAttribute("tokenIdValidateResult")
public TokenValidateResult validateTokenId(@RequestHeader HttpHeaders headers) {
System.out.println("ResourceController.validateTokenId()");
String tokenId = headers.getFirst("X-Auth-Token");
if (StringUtils.isEmpty(tokenId)) {
return TokenValidateResult.TOKEN_EMPTY;
}
for (Token token : TokenManager.userOfToken.values()) {
Date date = new Date();
if (tokenId.equals(token.getToken()) && ((date.getTime() - token.getCreate().getTime()) > (30L * 1000))) {// token有效期30秒
return TokenValidateResult.TOKEN_EXPIRED;
} else if (tokenId.equals(token.getToken())) {
return TokenValidateResult.SUCCESS;
}
}
return TokenValidateResult.TOKEN_NOT_EXIST;
}

最后写获取资源的方法

@RequestMapping(value = "{id}", method = RequestMethod.GET)
@ResponseBody

//ResponseEntity<?>注意这里泛型用了“?”,这样可以返回你想要的各种结果
public ResponseEntity<?> queryUserById(@PathVariable("id") Long id,
@ModelAttribute("tokenIdValidateResult") TokenValidateResult tokenIdValidateResult,
@RequestHeader HttpHeaders headers) {
try {
if (tokenIdValidateResult == TokenValidateResult.SUCCESS) {
User user = this.userService.queryUserById(id);
if (null == user) {
// 资源不存在,响应404
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
// 资源存在,响应200
// return ResponseEntity.status(HttpStatus.OK).body(user);
return ResponseEntity.ok(user);
} else if (tokenIdValidateResult == TokenValidateResult.TOKEN_EXPIRED) {//验证不通过的情况
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("token过期");
} else if (tokenIdValidateResult == TokenValidateResult.TOKEN_EMPTY) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("请填写token");
} else if (tokenIdValidateResult == TokenValidateResult.TOKEN_NOT_EXIST) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("token不存在");
}
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}

文章参考http://blog.csdn.net/kingmax54212008/article/details/51785634

原创粉丝点击