如今国内先后端不少公司都在使用先后端分离的开发方式,虽然也有不少人并不赞同先后端分离,好比如下这篇博客就颇有意思: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放入请求头中。