关于 REST 注册设计的问题

2017-09-01 09:02:59 +08:00
 lml12377

本来想 append 到之前一篇问题下面的:关于 REST authorization 授权设计的疑问,但是之前的经验发现 append 上去的内容都没人看,所以发了一个新的问题。

先理一下我的登陆流程:

  1. 用户访问登陆界面,填写信息
  2. web 后端校验验证码,并将 email/password 送给 api POST /authorization
  3. api 校验成功之后生成 token,集中存到 redis,之后将 token 返回给 web
  4. web 后端通过 session 存放 token,将其关联到用户的 cookie

此时用户处于已登陆状态,当用户想要访问需要登陆授权的资源时:

  1. web 后端从 session 中取出 token,加在 GET 参数上传送给 api
  2. api 拿着这个 token 去 redis 中查,从而拿到 uid
  3. api 将 uid 视为当前登陆用户的 ID,并查询相关资源

这个时候有个疑问:

我的注册流程是否需要加入到 REST api 中,去 github rest api 也没找到例子,如果加入的话,应该如何设计?

本来想的注册流程:

  1. 用户访问注册界面,填写信息(邮箱需要确认)
  2. web 后端拿到邮箱,向邮箱中发送一份包含验证链接的邮件,并将临时注册信息和生成的校验码 checkToken 在 session 中关联起来
  3. 暂时没有将临时注册信息放到库中,而是直接存到了 web 端的 session (会导致用户切换浏览器点击验证邮件无法验证,期望如此,不是设计缺陷),用户点击邮件中的链接,带着 checkToken 过来,web 拿来和 session 中的对比,一致,则将关联的临时注册信息送到 api
  4. api 接收到注册信息,POST 完成新增用户的操作,生成和 /authorization 时一致的 token,关联新生成的 uid 并存到 redis,返回用户信息和 token 给 web
  5. web 拿到 token,存到 session,视为已登陆

但是这里面有个问题,假设现在的注册 api 地址是 POST /register,那岂不是其他人都能访问,都可以往库里新增用户( api 可以限制 web 端的内网 ip,但是 app 必须得公网啊)?虽然用对称加密比如 AES 给 payload 加密可以避免这个问题,但总觉得不太合理。

希望各位有过设计经验的帮忙解答一下~

2720 次点击
所在节点    程序员
17 条回复
chenuu
2017-09-01 09:27:15 +08:00
注册 API 肯定得暴露出去啊,不过可以加些限制。比如多长时间内的请求次数;手机号做唯一性限制。
lml12377
2017-09-01 09:34:26 +08:00
@chenuu 本来 web 端设计那些验证就是为了得到一个有效的 email (手机号注册验证短信也是一样的道理),要是暴露出去,那废邮箱岂不是全进去了。。。而且 web 端还有 captcha,复杂的 captcha 至少能防刷,直接暴露,换 ip 就能无限刷( curl 就可以换 header )
artikle
2017-09-01 09:35:43 +08:00
1.图片验证码+短信验证码注册,校验短信验证码匹对成功 就将信息存入用户表,再返回 token 和一些用户信息
2.图片验证码注册+邮箱|手机短信激活,这种要么将未激活的帐号放到临时用户表,要么在用户表加个激活状态字段( 0 未激活 1 邮箱激活 2 手机激活 3 两者都激活)
对于 注册 api 地址是 POST /register,那岂不是其他人都能访问 这种问题一般都是加一些验证码或者拖动动态图片验证的
chenuu
2017-09-01 09:40:30 +08:00
@lml12377 你给他提供的邮箱发一个激活邮件呀!多久不激活就给他删掉。废又想怎么会进去。移动端也有验证码呀,有些滑动验证做的很复杂的。换 IP 能刷是个很正常的事情。curl 可以换 header,但是请求的 IP 她是不能通过 curl 改的。你可以试试,不要想当然。
你注册接口不让人访问,正常用户怎么注册?
lml12377
2017-09-01 09:40:41 +08:00
@artikle 哥我知道注册校验的流程怎么设计。。。还有这是 REST →_→,"对于 注册 api 地址是 POST /register,那岂不是其他人都能访问 这种问题一般都是加一些验证码或者拖动动态图片验证的",你说的这个是 web 端来做还是 api 来做?
lml12377
2017-09-01 09:41:13 +08:00
@chenuu
chenuu
2017-09-01 09:47:26 +08:00
cnblogs.com/LBSer/p/4083131.html 你看下这个。把桶放到足够小就差不多了。会误伤
artikle
2017-09-01 09:52:35 +08:00
@lml12377 前端做啊,你看看其他的网站,简单点的都是加图片验证码的,进入 web 的注册页面,生成一个图片验证码,前端填完其他的注册信息后,一并将验证码字段也通过注册接口传给后端,后端校验图片验证码是否正确,不对就注册不通过,当然这里面还有其他的校验,比如是否重复注册,调用次数,校验几次不通过就要等多久才能重新注册这些校验
zjp
2017-09-01 09:55:34 +08:00
我是参考了这篇文章的做法 http://www.webppd.com/thread-55-1-2.html 肯定要每个人都能访问啊…请求里加上时间戳和签名,并缓存邮箱地址。
baiyi
2017-09-01 10:35:24 +08:00
注册是否加入 API 中看你业务逻辑了, 不关 REST 的事

GitHub 没有注册也不是为了符合什么规范, 只是不想有人能在别处注册 GitHub 帐号罢了
Miy4mori
2017-09-01 10:43:43 +08:00
你的注册接口搞个验证码呗,
fcka
2017-09-01 10:46:47 +08:00
我只看到了跨域。。。
solee
2017-09-01 16:59:50 +08:00
注册肯定是一个接口没毛病。关键是你对这个接口的安全控制,手机号加验证码的验证,还是前后端配合的图形验证码验证。
lml12377
2017-09-06 17:20:35 +08:00
@baiyi 嗯,发现注册强行 rest 好像不太好实现,不过还是加到 api 里了(加了备注),web 后端拿到注册信息直接送给 api,api 校验后生成 token 和注册信息一起绑定到包含 email 的 redis key 上,发一封邮件,邮件的链接里包含 email 和 token,用户点击之后还是到 web,web 拿到 email 和 token 也是直接送到 api,api 拿着 email 去 redis 找,找到之后校验 token,校验成功将注册数据入库。

不过也看到 stackoverflow 上有将 session 当成 resource 加到 api 中的。
lml12377
2017-09-06 17:23:03 +08:00
@Miy4mori 注册信息之所以到 web 后端转一下,是因为发邮件想卡一下 captcha 校验,不过注册信息是 AES 加密送到 api 的,这个接口不对外开放
baiyi
2017-09-06 17:53:36 +08:00
@lml12377 #14 API 中加入注册是为了给其他调用你服务的人用的,如果你的业务只是在网站中注册的话,是没有必要将注册加入 API 中的,直接在后端注册就好了
lml12377
2017-09-06 21:48:28 +08:00
@baiyi 后端注册的话,app 还是要写接口,所以干脆就放到 api 里了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/387345

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX