您的位置:首页 > 其它

Api接口登录的鉴权方案

2020-05-05 21:52 253 查看

Api接口登录的鉴权方案
web登录和前后端分离方式的登录是不一样的,web登录成功主要靠的session,一但登录成功后客户端就会存储一个session_id,这样以后每次用户访问网页都会带着session_id,这样就能取得存放在服务端的session数据。
app登录就不能使用session,所以我们这里可以使用登录成功后要产生一个token值,以后用户每次访问app都要在header头带着这个token值,而这个token值需要一个过期时间。这个token值可以使用两种方案,一、可以在用户表上加上一个token字段和一个过期时间字段,二、可以使用JWT(json web token)这样就不需要将token值存入到数据库中
1 使用数据库
用户第一次注册成功后,往数据库中插入一条数据,同时生成一个token和token的过期时间,token的生成一定要具有唯一性。(token的生成可以使用md5(uniqid()));同时将token返回给客户端,客户端将token存起来,以后每次访问都带上这个token,这样我们就能先检测token是否存在,如果存在就可以查询用户信息,查到后然后对比过期时间就行,如果token不存在或者token不正确,或者过期返回重新登陆,登陆后也要重新生成token和token的过期时间,返回给客户端。
但是上面还是有风险,如果网络包中途被别人截获了,别人就可以发送http请求了,(当然我们已经做了基本的参数的验证,每次只能验证一次),我们的token也可像sign一样,当我们将token值返回给客户端后,以后再发送请求给app时我们不用带上token,带上的是token和时间戳一起通过AES算法加密的access_user_token,这样我们每次访问access_user_token 都是不一样的,我们在服务端验证时,首先判断传递access_user_token,如果有我在判断在redis中有无access_user_token值,如果有说明被验证过了,这个网络包就不安全了,如果没有,我们将access_user_token存入redis,然后进行解密,获得token后从数据库中查询。如果解密失败或者,数据库中没有数据或者时间过期了让用户重新登陆
2 使用JWT
我们也可以使用jwt,jwt是一种json web token ,当我们登陆成功或者注册成功后,我们可以使用jwt加密算法将用户的id通过jwt进行加密生成一个token值,我们可以把这个token值存入到客户端,这样客户端每次请求都会带上token值,我们的服务端拿到这个token值进行解密,如果解密失败或者时间过期,我们就让他重新登陆,如果解密成功我们就能获取用户的user_id,这样我们就能查到用户的信息了。
但是上面还是有风险,如果网络包中途被别人截获了,别人就可以发送http请求了,(当然我们已经做了基本的参数的验证,每次只能验证一次),我们的token也可像sign一样,当我们将token值返回给客户端后,以后再发送请求给app时我们不用带上token,带上的是token和时间戳一起通过AES算法加密的access_user_token,这样我们每次访问access_user_token 都是不一样的,我们在服务端验证时,首先判断传递access_user_token,如果有我在判断在redis中有无access_user_token值,如果有说明被验证过了,这个网络包就不安全了,如果没有,我们将access_user_token存入redis,然后进行解密,获得token后再使用jwt解密获得用户信息(比如用户的user_id)然后再从数据库中查询用户信息。如果解密失败或者数据库中没有数据或者时间过期了让用户重新登陆。可以参考:https://www.cnblogs.com/yehuisir/p/11521165.html

token和refresh_token的使用让我们的app登录状态永久性挂起。
即使是这样,不论我们使用哪种方式,token的过期时间原理上可以说是越短越安全,那么存在的问题就是token有一个过期时间,那么过期之后是不可能让用户重新输入用户名和密码来重新获取token的,那样完全违背了提升体验的初衷,相当于此功能是一个累赘了;
在token过期的情况,我们可以使用保存在手机本地的refresh_token去后台刷新一下token,重新获取一组令牌信息,覆盖掉以前保存在手机上的令牌信息,这也算是提升了一点安全性,为避免以前的令牌信息如果真落入别人之手
下面的例子是我用vue和jwt的案例
用户登录成功后我们同时生成token和refresh_token,token的时间是7200秒,refresh_token的时间是30天,为了后期拿refresh_token生成新的token方便,token中加密的数据和refresh_token加密的数据是一样的

我们每次都要验证token,如下图是验证token的中间件

我们的客户端收到返回50000的状态码是token不存在或者token错误,必须要重新登录,收到的50001的状态码是因为token过期,token过期后我们需要使用refresh_token 重新获得新的token和refresh_token



下面是验证refresh_token的中间件

如果验证refresh_token的中间件通过后重新生成新的token和refresh_token

这样就能实现我们的app上只需要登录一次,我们就不需要登录了,除非在30天内我们没有操作过我们的app导致refresh_token也失效了。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: