1. 程式人生 > >使用token和SpringMVC來實現安全的RESTFul介面

使用token和SpringMVC來實現安全的RESTFul介面

首先寫一個Controller,專門用於獲取token的

@Autowired
private UserService userService;

@RequestMapping(value = "/token", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<TokenResult> getToken(@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");//這個是客戶端傳過來的,客戶端要在請求頭中寫:X-Auth-Token和token值。也就是說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