在我当前的项目中,我正在使用OAuth2进行基于令牌的身份验证,以便访问Rest API,但是js可以读取这些令牌。因此和其他几个原因,我想将访问令牌存储在cookie中。
我已经上网了,无法找到将令牌放入cookie的方法。有人可以帮我吗?
答案 0 :(得分:0)
最后,找到了解决方案。我创建了一个/ login API,用于在cookie中设置访问令牌。
@PostMapping(consumes = "application/json")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest,
HttpServletResponse httpResponse) throws Exception {
ResponseEntity<?> result = null;
try {
String url = UriComponentsBuilder.fromHttpUrl(environment.getProperty("oauth.token.url"))
.queryParam("username", loginRequest.getUsername())
.queryParam("password", loginRequest.getPassword())
.queryParam("grant_type", OauthConstants.GRANT_TYPE_PASSWORD)
.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.add(AppConstants.AUTHORIZATION_HEADER, AppConstants.AUTH_HEADER_CLIENT_DEFAULT);
HttpEntity<String> httpEntity = new HttpEntity<>(headers);
ResponseEntity<HashMap> response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, HashMap.class);
Map<String, Object> authMap = response.getBody();
logger.info("Adding cookies");
String accessToken = (String) authMap.get(AppConstants.ACCESS_TOKEN);
String refreshToken = (String)authMap.get(AppConstants.REFRESH_TOKEN);
List<Cookie> cookies = new ArrayList<>();
cookies.add(newAppCookie(AppConstants.ACCESS_TOKEN, accessToken));
cookies.add(newAppCookie(AppConstants.REFRESH_TOKEN, refreshToken));
cookies.stream().forEach(c -> httpResponse.addCookie(c));
logger.info("Cookies added successfully");
result = ResponseEntity.ok(authMap);
} catch (HttpClientErrorException hex) {
logger.error("HttpClientErrorException occurred in login(): ", hex);
result = new ResponseEntity<>(hex.getResponseBodyAsString(),
HttpStatus.UNAUTHORIZED);
} catch (Exception e) {
logger.error("Exception occurred in login(): ", e);
throw e;
}
return result;
并且在用户登录后,对于服务器的每个API请求,都会应用一个过滤器来检查cookie中的访问令牌是否有效,如下所示。
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ApplicationOAuthFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(AuthFilter.class);
@Autowired
private Environment environment;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
if (httpRequest.getRequestURI().equals("/oauth/token")||
httpRequest.getRequestURI().equals("/login")) {
chain.doFilter(request, response);
return;
}
Cookie[] cookies = httpRequest.getCookies();
if (cookies == null) {
logger.info("No Cookies found");
chain.doFilter(request, response);
return;
}
Map<String,String> cookiesMap = Arrays.asList(cookies).stream().collect(Collectors.toMap(Cookie::getName, Cookie::getValue));
if (!cookiesMap.containsKey(AppConstants.ACCESS_TOKEN)) {
logger.info("No Access token found in cookie");
chain.doFilter(request, response);
return;
}
/**
* Proper request comes here.
*/
ApplicationRequestWrapper mutableRequest = new ApplicationRequestWrapper(httpRequest);
mutableRequest.putHeader("Authorization","Bearer "+ cookiesMap.get(AppConstants.ACCESS_TOKEN));
logger.info("Access token found in cookie");
chain.doFilter(mutableRequest, response);
}