先说传统MVC网站的网页受权流程。前端
1.用户发起了某个须要登陆执行的操做数据库
2.收集AppId等信息重定向到微信服务器后端
3.微信服务器回调到网站某个Controller的Actionapi
4.在此Action下经过获得的code请求获得access_token,并用a_t进一步获取用户信息,至此受权流程完成,能够保存用户信息到数据库和cookie,重定向回原页面浏览器
SPA架构下的问题安全
1.服务端与前端之间不保证可信,须要认证交互服务器
2.使用WebApi交互,没法在服务端控制前端的页面跳转微信
3.认证过程当中有安全级别较高的数据(access_token),不该该暴露在客户端,直接致使认证流程必须前端与WebApi配合完成cookie
这里给出一张基于ng2的先后端分离的SPA的交互流程图,只须要关心右下部分须要用户数据但localStorage中没有(也就是说用户未登陆)的状况。session
这里给出了三条登陆方式,前两种(QQ与微信的受权登陆)均是第三方平台的OAuth2认证登陆方式,第三种是暂没必要实现但早晚会加入的用户注册登陆方式,为了支持多种方式(受权或注册),必须给出很通用可扩展的登陆流程。
来谈微信受权的流程
1.第一步确定是发起受权,即引导用户点击url重定向到微信的api,通常的实现都是location.href直接重定向。
注意:第一步完成后实际上用户浏览器已经丢失客户端页面了,页面已经到了微信的受权页面,这是微信的站点
2.当用户点击赞成受权后微信会生成一个code和state并请求咱们提供的redirect_uri,此uri必须是前端页面。
传统MVC网站下页面的Action与WebApi概念没必要区分的很清楚,给人的感受就是你写了一个redirect_uri(好比/OAuth/Callback),微信就传参数到这个action,这个action处理完后一个重定向就回到原页面结束了,代码全都是服务端语言来实现。可是单页应用下,服务器概念移除,这个回调页面就得是某个前端页面,而后在这个页面里处理微信传来的参数。
3.微信回调到前端页面获得的参数只有一个发起时带上的state(能够用来定向回发起页)和一个code(只能使用一次且很快过时),因此如今必须用code来换取access_token,再用access_token换取实际用户信息,这些事情显而易见不该该由客户端来完成。
4.客户端用code请求WebApi,由WebApi进行后续的access_token与用户信息获取操做。
受权的发起须要的参数仅为AppId,不须要AppSecret,因此此操做由客户端进行彻底没问题,可是获得code后的后续请求的数据安全系数很高,因此必定要由安全的服务器来实现,也就是WebApi。
5.具体的流程视需求而定,总而言之假设WebApi如今经过code已经完成了用户信息的获取与保存,那就将必要的登陆信息返回给前端,前端再将其保存到localStorage便可。
6.后续再遇到须要登陆数据的业务时,先从localStorage获取,这是正经常使用户已登陆的场景(localStorage可能太过暴力,也能够用sessionStorage),一旦本地没有了登陆数据,则回到步骤1从新发起受权,完美。
注意:登陆数据保存在客户端是必须的事情,但必定不要保存重要敏感数据,客户端的任何数据都应该视为不可靠数据,只能作一些假设,假设只要提供给了WebApi特定的数据,就视此次请求为合法请求,并尽可能增长请求伪造的门槛。