app登录浅析

1.登录方式

(1)登录方式

一般有以下几种登录方式

传统的账号密码登录,如下面的知乎账号/密码 登录,账号可以是邮箱,手机号或者账户名

《app登录浅析》 20170301165358389.jpg

手机验证码登录,如下面的今日头条手机验证码登录

《app登录浅析》 812786ce-b10c-42b1-84db-1b1c26b4f480.jpg

第三方登录,如下面的额知乎日报,上面的今日头条也一样

《app登录浅析》 20170301165358482.jpg

还有一些新型的登录方式,比如图案锁,指纹,语音验证,虹膜扫描等等,这些都是在client进行验证,或者是一种变种的账号密码形式,在这里不作讨论。`为表述方便,分别使用 账密验证码第三方来表述上面三种登录方式。

(2)登录方式的大概流程

账密:用户在client输入账号密码,发送到server端,server端进行database验证,如果验证通过则该用户认证成功,否则认证失败

验证码:用户输入手机号,并且点击获取验证码,server产生随机验证码并打上过期时间,通过SMS传输给用户,client输入该验证码,传到server进行判断

第三方:第三方相对复杂一点,client需要先到第三方网站或者APP进行授权,授权后跳转到server,server通过code码获取到相应的access_token,然后通过access_token获得这个用户在这个第三方的基本信息。

(3)登录方式的优缺点以及适用场景

账密:安全性相对较高,需要用户输入保护信息。使用场景较广,一般的应用都能够适用。

验证码:优点是便捷,缺点是安全系数相对较低,手机丢失即账号丢失,一般用在验证不是非常严密的应用,比如新闻资讯,地图这种获取咨询的app或者一些即用即关的一些应用,比如滴滴,货拉拉这种app,(注:内部支付有另外的验证)。

第三方:优点同样是便捷,比手机号还要便捷,都不需要输入验证码。安全性需要依托第三方的可信度。不过现在微信,微博等第三方的登录还是相对比较安全的。使用范围相对较广。便捷性方面不定,需要依托第三方的便捷性,比如微信就是需要安装微信的app,而有些第三方登录会跳转到该第三方的登录网站中,使用账号密码登录。所以安全性方面需要看第三方了,像微信这样的直接点击确定登录肯定没有输入第三方账号密码安全。综合来讲第三方登录安全性不差,便捷性较高,另外不用注册新的账号密码,在现在的登录方式中非常普遍。

2.认证(Authentication)

首先普及两个知识点:

a.认证(Authentication)和授权(Authorization)。借用别人的一个例子,你要登陆论坛,输入用户名张三,密码1234,密码正确,证明你张三确实是张三,这就是 authentication;再一check用户张三是个版主,所以有权限加精删别人帖,这就是 authorization。

b.token:token就是令牌的意思。为什么client中使用token代替cookie/session呢?token去掉了服务器端的状态保持,扩展性更好,不需要在服务器进行存储,只需要验证就好。

(1)账密认证

《app登录浅析》 b1b31c5f-d4ad-44b4-ae2a-3092b2e5474a.png

Client指的是移动终端,Application指的是应用服务器。
账密的认证很简单,数据库验证下就行。

注意:密码一般都会使用MD5进行hash下

(2)验证码认证

《app登录浅析》 7a677b0f-fe50-48a1-b75c-cbdfb4e1fd31.png

比账号密码多了步产生验证码的过程,并且匹配一般在缓存数据库(如memcache或者redis)中进行,验证是需要验证过期时间。

(3)第三方认证

对于说使用友盟和shareSDK的同学,这篇文章不是讲怎么做,而是表述一些我在APP登录方面的一些见解,以及原理剖析。
为了描述清楚,使用微信作为代表(事先需要到各个第三方网站注册自己的server Application)

《app登录浅析》 48b94db0-b693-45e5-a5ba-fad463fb43d6.png

步骤如下:

1.client点击微信图标登录,带上Application ID和scope,这些都是在你注册Application的时候可以看到的

2.微信SDK会调用本地接口,打开微信的授权页,如下:

《app登录浅析》 0.09139273746920629.png

3.点击确定登录,微信server验证用户,然后会redirect to 你的Application server,带上code码

4.code码的有效期很短,需要立即使用code码用API从微信server换取access_token等验证数据

5.application获取到token后就能将这些数据存储到数据库,(数据库具体格式后面会有介绍)。并且通过access_token从微信server拿到用户的一些基本信息,比如头像,昵称等等。

6.有些应用不允许单独社交账号存在,必须绑定手机号码/密码,因此对于不同的业务,不同的场景各自去做。这其实也是一大块,手机号码的绑定,解绑,注册,第三方账号的绑定解绑,绑定到另外的手机号,密码找回,是否用手机号为主账号,等等等等一系列的业务逻辑,各个公司各个产品因为安全性能要求和设计不同,表现形式也是多种多样。在这里不做详细的探讨了,有兴趣的同学可以自己去梳理梳理。

7.application server产生自己的access_token,返回给client,client进行用户数据的访问和API的调用。

关于微信的第三方登录流程具体的可以去微信开放平台 中的->资源中心->移动应用->微信登录功能。其他的平台都差不多。
Client始终没有拿到第三方的token,是因为client获取第三方数据完全可以通过server中转,这样就避免将token暴露给Client,这样第三方中用户的数据也会更加安全

3.授权(Authorization)

对于不同的登录方式会有不同的认证过程,但是授权就需要进行统一管理。

授权的关键点在于怎么产生一个好的access_token让client进行数据访问。oAuth2是一个很好的解决方案,JWT(JSON Web Token)是目前比较流行也比较安全的一种token产生和验证机制。
当然也可以自己产生token,一般使用”时间戳+UserGuid+椒盐噪声”然后非对称加密,传输给Client。JWT是一种更加规范,更加安全的Token的生成和校验方式。
jwt
jwt规范
JWT的介绍看这里

授权过程:

(1)认证成功后,得到或者生成UserGuid(用户的唯一id码,同一个账户的不同登录方式拥有同一个UserGuid),然后通过JWT生成token,token中包含UserGuid,token过期时间等等。
(2)将JWT token传送给client,client收到后保存下来。之后在向服务器请求数据时带在Header上
(3)服务器收到client的请求,然后使用中间件进行JWT拆分,得到其中的token过期时间,UserId以及其他一些Claims。根据其中的Claim进行身份校验,这里不同的server有不同的操作。

注意:1.JWT token是明文传输的,可以通过base64url_decode获得其中的Claims信息,因此不要将敏感信息放进去
2.JWT的安全:因为JWT的第三部分是通过HS256加密的,所以client不能够通过Claims进行仿造token,这样会导致在server校验不通过。但是如果整个token被盗取了就没有办法了,毕竟这个tokn是所有请求权限的令牌。当然也可以通过在token中添加设备码等信息进一步加强其安全性。
3.token过期刷新问题:如果server检查到client的token过期,就会返回401错误。而一般的token设置有效期不长,总不能每次过期就重新登录吧。有两个解决方案。一是在在有效时间,比如在时间到达有效时间的3/4时,就开始向客户端推送新的token,最极端的做法是每次请求都换token,这样安全性高,但是太费server资源,并且在高并发情况下会有旧的请求被否决的情况。还有一种方案,就是在过期时间外再设定一个刷新时间期限的Claim,这个时间设定长一些,跟OAuth2中的refresh_token相似。当检测到token过期时,查看刷新时间过期没有,如果没有过期,则重新生成JWT token返回给client。

4.server端数据库设计

用户登录模块在数据库模块也需要好好设计,不能因为每添加一种第三方认证就修改数据库表。

(1)用户基本信息表User

UserIDavatarname
2url1name1
1url2name2
3url3name3

用户基本信息表包含一些用户基本信息,主键是用户的UserGuid,是唯一的。

(2)用户验证表User_auths

primaryUserIDidentity_typeidentifycredentialisFirstParty
12emailmy-emailMD5MD5MD5True
22accountaccountNameaccountPwMD5True
31phone12345678909pwMD5True
42wechatwechatIDaccess_token & refresh_tokenFalse
53weiboweiboIDaccess_token & refresh_tokenFalse

用户验证表,包含用户的各种登录方式,对列名解释:primaryKey:主键,唯一。UserGuid:用户唯一标识,在表中不唯一。identity_type:登录方式。identify:该方式的账户名或ID。isFirstParty:是否是第一方登录。credential:对于第一方是密码,对于第三方是access_tokenrefresh_token

很多现在的APP第三方登录成功获得用户基本资料后便丢弃第三方的access_tokenrefresh_token,其实如果为了真正的安全,还是需要保存下来,每次自动登录后通过第三方access_tokenrefresh_token来更新用户信息以及验证用户是否是真实身份。
UserGuid不唯一,可能有多个账号对应同一个UserGuid(第三方绑定到电话账号等等)。使用isFirstParty来标注是否是第一方,对于有些应用email/phone/accout的密码是同一个,修改的话就需要同时修改,需要通过标志位来定位这些第一方账号。

    原文作者:Daniel_adu
    原文地址: https://www.jianshu.com/p/c95c4741d725
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞