账号密码登录
收集用户输入的用户名和密码,发送给后端和数据库比对验证,用户是否存在,密码是否正确,都OK就返回登录成功和用户信息等
有的会加一个形验证码之类的,就是调接口,然后后端随机生成形验证码,并存到session或者token(取决于你项目采用的登录验证方式,在本文下一章节),然后发送给前端展示
前端点登录的时候收集用户输入的验证码,和后端比对,都OK就返回登录成功和用户信息等
手机验证码登录、邮箱登录
比如手机验证码登录前端点击发送验证码,把手机号传给后端,后端生成随机数,然后把号码和完整的短信内容(包括随机数)都发送给第三方短信平台(比如阿里、云片…一大堆)
这里有的人是在第三方短信发送成功的回调里把手机号和随机数存到数据库也有的人是生成好随机数后,就把号码和随机数存到数据库里,第三方返回的回调再update一下比如发送的短信内容不符合规范,短信平台没钱了,短信平台异常等也有个记录日志在那里
用户收到短信后点登录,前端收集手机号和验证码传给后端和数据库进行对比,验证成功就返回登录成功和用户信息等
邮箱验证码和手机验证码逻辑基本都是一样的,用第三方邮箱平台,然后接收验证码的地方由手机号变为邮箱号
第三方账号快捷登录
首先第三方账号登录都需要去申请授权的比如QQ、微信
前端进入登录页面的时候调接口获取跳转到第三方登录页面的链接地址(最好不要前端这边写死),这个地址上拼接了后端加密过后的签名、登录成功后的回跳地址(redirect_ur等(具体可以看第三方登录的官方文档需要传一些什么)
QQ登录地址示例
https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=101958498&redirect_uri=http%3A%2F%2Fniuj.uuuqwr.cn%2Findex.html%23%2Foauth_login%2Fqq&state=24c123db52d1136c7560638325fbdab4&scope=get_user_info,list_album,upload_pic
需要注意的是这个回调地址(redirect_ur,得是在你的项目里的一个单独的专门的页面,就是专门接收登录成功后回调链接上带过来的参数操行一些操作,更改登录状态的,不能是你的项目的登录页面或者个人中心之类的
然后我们在这个页面登录的时候,第三方会以同样的方式生成签名并获取URL中的签名来对比,对比成功就说明可以登录,然后把验证通过的参数code等拼接到URL里携带的redirect_uri地址上再跳转过去
前端在这个回跳地址页面,拿到之后再传给后端,然后后端再调第三方的接口,拿到这个登录的用户的openId、unionId,和数据库的对比,没有就注册用户,并保存openId、unionId
然后就给前端返回登录成功状态,也有的需要再让你绑定手机号才给你登录成功,这里具体要看你的业务需求,前端再根据返回不同的状态进行登录成功还是绑定后机号等操作
比如微信登录,根据后端返回的redirect_uri和AppId等信息,在当前页面生成二维码,或者打开新标签页跳转到单独的扫码页面
比如在当前页面生成二维码,使用的是vue-wxlogin,先安装
然后扫码登录后的流程就和QQ快捷登录后的流程基本上一模一样了
App扫码登录使用的是vue-qr,先安装
流程是这样的
进入页面首先获取生成二维码所需要的信息,调接口然后后端生成比如uuid等,并设置设置过期时间存到缓存中,然后把信息uuid等返回给前端前端拿到信息后,用这些信息作为上述代码中的url,生成二维码,接着调用另一个接口把uuid传过去,并开启轮循、或者长连接,或者不调接口直接用WebSocket监听。具体使用哪一个看自己的业务需求或者和后端商量然后手机端这边肯定是处于登录状态的,不然也没法扫码登录,然后App扫码,就会获取到二维码中的uuid接着手机端点登录之后,就把uuid和这个登录了手机端的用户账号信息,发送给后端后端拿到登录的这个帐号信息,通过WebSocket发送给前端,就登录成功了。或者修改缓存中的值,比如把uuid存起来的时候是把uuid作为key,但是没有值,然后轮询接口就是获取这个uuid的值,没登录之前获取的就是个空的,App点登录之后,后端把拿到的用户信息等作为值赋给对应的uuid,前端这边轮询查到的数据就不是空的了,就说明登录成功,然后后端再清掉这个缓存
指纹登录、刷脸登录、本机号码免密一键登录这个都是用于移动端也就是iOS和Android,而且都需要SDK
大致流程应该是需要一个用户确认开通这些功能的页面,或者授权获取信息弹窗等方式,让用户授权
比如是本机号码免密一键登录,在接入SDK之后,通过SDK与运营商通信来获得用户手机号码
然后用户点击一键登录授权,通过网关取号对比,并返回对比结果实现一键登录
后续验证登录流程Cookie+Session
首次登录验证成功之后,后端会创建一个Session对象然后保存到缓存或者数据库里然后在响应登录接口的响应头里,设置Set-Cookie字段,并把SessionId等信息写入进去,并设置过期时间,这些信息就是Cookie,然后浏览器会保存这些Cookie信息然后之后再发送请求的时候,如果当前域名有保存Cookie信息的话,浏览器会自动在请求头上添加Cookie字段,并带上保存的Cookie信息然后后端接收到请求后,会把请求头中的Cookie信息提取出来和存在服务器的对应的Session信息作对比,如果一致就说明登录验证成功了,不需要再重复登录
缺点主要是CSRF攻击:因为Session是基于Cookie识别的,如果Cookie被截获,然后人家就可以利用我们的Cookie信息跳过登录,直接进入登录状态,发起跨站伪造请求
然后是如果把Session存在服务器内存,没有存到数据库的话,还会有以下问题
多服务器无法共享:比如我们登录的时候,我们网站不同的资源可能存在不同的服务器,当我们请求另一台服务器时里面就没有Session信息,就会被认为没有登录过。所以导致这种方式的话,前端代码和后端代码都只能放在同一台服务器上服务器压力大:因为用户登录后的Session信息是存在内存里,如果用户量很大,服务器压力也会增
Token流程和上面Session差不多
首次登录验证成功之后,后端一般使用JWT将用户信息、签名等加密生成一串字符串,存到数据库并返回给前端前端再存起来,存在Cookie、SessionStorage、LocalStorage都可以之后再次请求时浏览器也不会默认携带,需要我们自己在请求拦截器里添加请求头,把Token信息带上然后后端就拿到Token信息来查找数据库里有没有,如果有再执行查询数据库操作等返回前端请求的数据,因为设置了过期时间的话,时间到了Redis会自动就删掉数据库里的Token,查询就不会有。当然也有人是开定时任务去删也有的人不把Token存在数据库,而是生成Token的时候,把用户信息,过期时间等一起加密发给前端,之后再请求时,后端拿到Token就先解密,再查询解密出来的用户信息,如果查询到了并且也没有过期,就查询返回前端请求的数据
比如不允许多端登录,一边登录就要把另一边挤下线,意思就是一个账号只有允许一个Token,然后其他地方登录,就会生成新的Token再存到数据库,就把之前的给替换掉了,那么用之前的Token登录的地方就会下线了反之,如果需要允许多端登录,也就是说一个用户可以有多个Token了
优点
更安全:因为可以不用发送Cookie了,能够避免CSRF攻击。也不需要操作Session了多服务器方便共享:前后端代码文件等资源放在不同的服务器,请求时都能获取到正确的登录状态
单点登录(SSO)简单说就是在一个应用注册的账号可以同时在多个应用上登陆
比如淘宝+天猫+支付宝+阿里巴巴…,这几个随便登陆哪一个,再打开其他几个的网站就会自动进入登录状态
它的登录方式就是本文第一章介绍的那些,后续验证方式也就是本文第二章介绍的那些,都介绍过了
关键一个点就是怎么把多个应用给联系起来?
还有使用Cookie的话,Cookie本身有限制不能跨域,那还得需要解决这个问题
而且在同域下的不同域下的单点登陆也是有区别的,网上看过不少资料都说的不清不楚的,我也没做过这种多应用的单点登录,所以这里只总结了一下大致流程,自己记录一下,后面做一遍再完善吧
同域比如百度(baidu.co、百度网盘(pabaidu.co、百度贴吧(tiebbaidu.co、百度地(map.baidu.co…
这种情况下实现单点登录首先需要把Cookie设置给顶级域,这样子他下面所有的子域都可以访问他的Cookie
然后通过Redis、Tomcat等,都可以把Session设置成在这几个域名里共享
这样就把几个应用联系起来了,然后其他流程和上面就差不多了
不同域比如淘宝(taobao.co、天猫(tmalco、支付宝(alipay.co、阿里巴巴(168co…
同域的情况下我们还可以通过顶级域共享Cookie,可这种域名完全不同的情况下Cookie就不能共享了,那怎么办呢?
所以为了解决这个问题,我们就需要一个独立的能够统一管理或者共享这些状态信息的认证中心(CAS),也就是SSO登录系统,或者可以理解为一个中转站
比如我们现在有两个站点:com和com需要共享登录状态
登录首先在没有登录的情况下,进入com/user需要登录的页面时,发现没有登录时,就会重定向到认证中心,并且把自己的地址作为参数,比如
然后认证中心发现登录的请求中没有Ticket也就是用户没有登录,就转到登录页面,所有的登录都在认证中心里进行
然后用户输入信息提交登录申请后,认证中心会校验用户信息校验通过后,会生成一个授权码Ticket,并将认证中心的登录状态写入Cookie,再重写向到先前的页面,并带上Ticket
然后com/user拿到Ticket后再向认证中心确认,授权码是不是有效,验证成功之后,服务器再把登录信息写入Cookie,返回给前端保存起来,这时候com就有两个Cookie了,分别是自己和认证中心的登录状态,也就是登录成功了
为什么拿到Ticket后还要再向认证中心确认?因为如果不再次验证的话,比如我们直接在地址栏输入回调的地址,并且拼接上假的信息参数,不就直接认为登录了嘛,这当然不行,所以需要再验证一下
然后com也访问需要登录的页面,重写向到认证中心时,发现有之前登录过的Cookie,所以直接下发Ticket给com
然后com拿到Ticket后再向认证中心验证,验证成功就把登录信息写入Cookie返回给前端保存起来,这时候就是登录状态了,而不会进入到登录页面
注销
就是当一个应用上退出登录,其他所有共享登录的应用全都自动退出登录
比如com退出登录时,先清空自身的登录状态Cookie,再携带Ticket请求认证中心的退出api
然后认证中心验证Ticket有效之后,遍历下这个授权码下对应的所有应用,调用对应的退出api
就完成了所有应用的退出
单点登录的优缺点优点
用户体验好,不需要记住多个账号和密码提高开发效率方便管理
缺点
不利于重构,因为涉及到的系统多,要重构的话需要兼容所有系统,就很麻烦存在安全隐患,毕竟只需要登录一次,所有授权的应用都可以直接访问,就可能导致一些信息泄露
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点