如今國內先後端不少公司都在使用先後端分離的開發方式,雖然也有不少人並不贊同先後端分離,好比如下這篇博客就頗有意思:html
https://www.aliyun.com/jiaocheng/650661.html前端
咱們從技術角度來看的話:node
http://blog.jobbole.com/111624/
http://www.360doc.com/content/18/0511/06/36490684_752894279.shtmlweb
摘要:spring
固然,站在個人角度,CTO要求咱們用先後端分離我就用好了,先後端分離的權限控制問題要稍微複雜一些,咱們最近的項目採用security+jwt的方式來實現先後端分離的權限控制。編程
Spring Security是一個可以爲基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組能夠在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面編程)功能,爲應用系統提供聲明式的安全訪問控制功能,減小了爲企業系統安全控制編寫大量重複代碼的工做。json
關於security的其餘知識能夠看:後端
http://www.javashuo.com/article/p-qyodtway-eg.htmlapi
Json web token (JWT),是爲了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519)。該標準被設計爲緊湊且安全的,通常被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也能夠增長一些額外的其它業務邏輯所必須的聲明信息。固然該標準也可直接被用於認證,也可被加密。安全
關於JWT能夠看下面這篇博客:
https://www.cnblogs.com/jiangwz/p/9503914.html
spring security + jwt的具體實現思路是:
用戶登錄後臺,後臺生成一個jwt簽名返回給前端,前端每次請求將簽名放在Header,後臺驗證簽名是否正確。
關於security的部分這裏再也不贅述
jwt
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency>
驗證token
public class JwtAuthenticationTokenFilter extends UsernamePasswordAuthenticationFilter { @Autowired private CustomerUserDetailsService userDetailsService; @Autowired private JwtTokenUtil jwtTokenUtil; private String tokenHeader="Authorization"; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResopnse = (HttpServletResponse) response; if("OPTIONS".equalsIgnoreCase(httpRequest.getMethod())) { httpResopnse.setStatus(HttpServletResponse.SC_OK); } else { String authToken = httpRequest.getHeader(this.tokenHeader); if(authToken!=null) authToken =authToken.substring(7); String username = jwtTokenUtil.getUsernameFromToken(authToken); if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); if (jwtTokenUtil.validateToken(authToken, userDetails)) { UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest)); SecurityContextHolder.getContext().setAuthentication(authentication); } } chain.doFilter(request, response); } } }
JWT工具類中,根據USER信息生成token
public String generateToken(UserDetails userDetails) { Map<String, Object> claims = new HashMap<>(); claims.put(CLAIM_KEY_CREATED, new Date()); ...... return generateToken(claims); }
而後前端須要在每次的請求中將這個token放入請求頭中。