1
kisshere 2015-01-13 16:43:50 +08:00 via Android 1
每次请求的时候附带一个参数也可以啊,这个参数把user_id和username进行可逆式加密不就得了,服务器端再解密一次判断是否正确就OK啦,何必查询数据库
|
2
andybest 2015-01-13 16:49:08 +08:00
“手机端又不是浏览器,怎么会有session”
到这句对话就应该终止了 |
5
Havee 2015-01-13 16:55:41 +08:00 3
确实想多了,前提是赶工
怎么实现你管人家干嘛,后期需要优化的时候拿数据出来说事呗 说话方式也有些问题,不要质疑对方,一质疑,对方就被如被踩着尾巴跳出来了 就算要对方改,也不要用引导的方式(如果你们是平级的话),引导用不好容易让对方认为你含沙射影,直接提出来 譬如,兄弟,你这样每次查数据库给我很大压力呀,帮帮忙咯,后面请你吃饭。 然后对方改是因为帮助你,对方有成就感,而不是被质疑 |
8
niboy 2015-01-13 17:10:56 +08:00 1
只抛出问题,然后他怎么解决就由他了。
|
9
yuankui OP |
10
lincanbin 2015-01-13 17:13:55 +08:00 via Android
Api编程一般是在URL中构造Auth参数,例如携带一个token,cookie确实是低效的做法,Api编程中基本见不到。
另外真没那么复杂,一般只要把Auth参数加入封装的发包类就行,复杂度肯定是低于cookie的 |
12
yuankui OP @niboy 谢谢,这个思路不错。不过有时间的情况是,我认为是问题的问题,别人不会认为是问题,他就不会去弄。我如果弄的话,又会遭到他的反感:你怎么能随便改我的设计之类的。。
|
13
yuankui OP |
14
oott123 2015-01-13 17:19:44 +08:00
其实我觉得加个缓存有什么问题么……
倒是你提到的 cookies 确实会加大客户端开发难度…… 唔,就算我们这里不考虑 cookies ,采用其它的 session 的实现,一般情况下都是存一个 token 吧。(你不会想告诉我说你要在 session 里存用户名和密码吧……难道存 uid: 1, auth: true 么……) 存一个 token 的话……就对服务器负载而言,和用缓存并未有很显然的区别吧。 |
16
zhicheng 2015-01-13 17:23:00 +08:00
|
17
huigeer 2015-01-13 17:25:20 +08:00
引导不成功, 估计以后难相处, 奏请cto, 开会讨论技术问题, 顺带纠正态度问题
|
18
foursking 2015-01-13 17:27:46 +08:00
你们有上级吗 有的话找上级谈下这个问题,程序员之间还是沟通顺利最重要
|
22
kisshere 2015-01-13 17:34:36 +08:00 via Android
@zhicheng 加密在服务器端生成,可逆式加密在so上面一搜一大把,这串code我可以随便暴露给任何人看,你即使能拿到加密后的code能反解它么,我可以用userid和12345的倍数(随机数)来生成密文code,服务器接收到密文后,反解它,看是否是由一个int值和一个12345倍数组成的值构成
|
24
turing 2015-01-13 17:39:34 +08:00
不建议用 cookie,可以尝试一下 jwt
|
25
zhicheng 2015-01-13 17:40:27 +08:00
@kisshere 可逆加密就是可以反解的。我说的是你用来加密解密的那个密码,这个密码可能开发或者运维都可以看到的。
另外注意一点,加密算法不要随便找一个就拿来用。 |
27
learnshare 2015-01-13 17:47:26 +08:00
从技术上讲,这种认证方式不可以用。很多同志喜欢摆工作年限、资历,那能代表啥?
对于技术问题,最好的办法就是一堆搞技术的一起讨论,这样不至于有一个扯淡的结论。 但对于人情面子这种事,还是要顾及一下。毕竟都不是小孩子了,让人家觉得打脸的事应该偷偷摸摸干。 |
28
zhicheng 2015-01-13 17:49:39 +08:00
@kisshere 当然对于有些不是非常重要的小项目,我也会偷懒直接把认证信息存到 Cookie 或者 URL 里,不过我用的不是可逆加密算法,而是用的 HMAC 。
|
29
liaojinxing 2015-01-13 17:50:19 +08:00
参考github的api设计,https+token
|
30
jeequ 2015-01-13 17:50:47 +08:00 1
看完这文章,感觉你为什么会拿这么点小事来放在这里让大家讨论?
我觉着你们说话的方式,从字面上来说,感觉没有任何问题。 (同学:呵呵,你想多了,没那么复杂的) 这句话证明这位同学有足够信心能够解决缓存的问题了,更何况你们要解决就是缓存的问题吧。 对话应该是这样的: (同学:呵呵,你想多了,没那么复杂的) (我:不复杂啊?那行,按你的想法把缓存的问题解决了就行) 楼主是如何回答的呢? |
31
PP 2015-01-13 17:51:53 +08:00 2
这类状况一般包含两个环节,一是技术取舍,二是沟通技巧。在技术方面,只要不涉及根本性问题,都可以商量着来,必要的妥协也是可以接受的。在沟通方面,您和贵同事都不大擅长,特别是在本事例中,您的责任还要大一些。具体来说,您初始提问的方式带有一定攻击性,“这个验证模块”和“你这个验证模块”的差异还是很大的,后续的一些争论也在不断的质疑对方的技术实力,把贵同事逼到了墙角,导致贵同事没有更多的选择。如果您在与同事讨论技术问题时将重心放在问题本身而不是对方身上,相信与您沟通的对象就不会有那么大的防御压力和负面反应。技术问题没人永远正确,沟通能力提升永无止境,和气一些比较好。
|
32
fising 2015-01-13 17:57:04 +08:00
看完了,觉得是楼主自己有问题。
|
34
lenmore 2015-01-13 18:00:51 +08:00
我觉得这位程序员做法没问题啊,以最小的代价换得性能提升,对客户端透明,这样最好了。
而且项目既然比较赶,现在突然提出这么个需求来,客户端也会有意见,你又怎么去摆平呢? |
39
sumhat 2015-01-13 18:20:26 +08:00
论 spec 和 design review 的重要性。
|
42
skybr 2015-01-13 18:29:04 +08:00
我感觉你不走db或cache而只想通过session解决是只想记一个session["user.id"]这种方案?
但这样会出现一个问题, 在A设备上修改密码后原先在B设备上用老密码登录成功的还是有效的。 除非你在去维护一个session和user.id的映射关系, 然后人为销毁这些session; 或者你在session除了user.id外再设置一个user.token验证合法性, 某个终端修改后重设 , 但做验证的时候同样无法避免走一遍db或者cache. 你同事的办法虽然有点糙, 但要是保障走https, 反而比你的想法问题小. |
43
kemingcao 2015-01-13 18:31:59 +08:00
这样的做法,我会推倒他的代码,自己花费半天时间把用户认证测试写出来。
|
44
jarlyyn 2015-01-13 18:34:11 +08:00
觉你的同事没什么大问题啊。这不就是一个HTTP basic验证么。在oauth普及前本来也是一个比较常见的api解决方案吧。
以REST来说,不用session也算 符合 state-less的标准啊。 既然你的问题是是否每次都需要查询数据库,那么的确做个缓存就可以了…… 其实session也要考虑很多问题啊。客户端的储存与过期处理,服务器端的集群处理,用户session的注销等。 既然缓存能解决,何必用更重的session呢。 |
45
Jaylee 2015-01-13 18:44:13 +08:00
session是一个缓存?
|
46
paulw54jrn 2015-01-13 18:44:34 +08:00
@skybr
用缓存的话,如果别的客户端改密码,只需要去缓存里面把记录失效就可以了? |
47
Hubert 2015-01-13 19:01:16 +08:00 2
首先,如果你是在问你同事的解决方案有没有问题,作为一个渣程序员,我觉得在你描述的应用场景里面,你那同事做的是没有任何问题的。
你们做的是一个 API 服务器端,Session 、Cookie 这种玩意确实不是 API 身份验证好的解决方案。目前比较流行的应该是 OAuth,OAuth2 (目前各大开放平台 API 基本上都是用的这玩意)。@Jarlyyn 说了,在 OAuth 还没普及的时候 HTTP Basic 验证是一种很长见的验证方式。目前存在的问题是:每次查询数据库,但是你又说了,这是一个急着上线的项目,所以不盲目的做这种优化也没什么错。 个人浅见,缓存比 Session、Cookie 这种玩意靠谱多了。 如果你是问你跟你同事交流方面的问题,那我也觉得你同事没什么错。 一、你提的方案不正确,如果用你的方案 ,你到时候会发现这么多么坑爹的一件事情。 二、他面对你提的这种不合理的要求,还心平气和的跟你说,我觉得在程序员中,你同事的脾气应该算好的了。 三、“该同事工作经验应该算比我多个2-3年,他是不会会觉得我提出的办法比他好(假如),他会没面子”,从你这个言论来看,我觉得你心态没有你同事好。 |
48
yuankui OP @Hubert 感谢你废了这么多口舌来跟我讲道理。
你们的话我会参考 场景里面可能涉及更多的背景和细节,可能是我也没能交待清楚,大家也忽略的东西。 所以还是谢谢大家的意见,我会好好反省,出一个比较好的结论,以及一个长期的解决方案(沟通方面)。 |
49
jarlyyn 2015-01-13 19:17:14 +08:00
@paulw54jrn 不需要失效,直接更新缓存就可以了。
假设缓存是 username对应hash后的密码的话 |
50
njutree 2015-01-13 19:23:12 +08:00
我觉得这就是你们公司没有统一做程序架构或设计的结果,每个人都有自己的设计思路导致项目里面很多耦合不必要的(轮子),而且没发统一。
|
51
jarlyyn 2015-01-13 19:41:58 +08:00
@yuankui
就沟通本身来说,我觉得你有个问题。 你只是提出了一个自己的觉得能够解决问题的方案, 你所有的沟通都没有否定对方的方案有效。 你也没有解决'有些人就是不愿意写session'的问题。 你在没有说服别人的请跨下(既没有证明别人的方法无效,也没有证明自己的发放更好),却认为别人难以沟通,这才是问题。 PS,如果是session和http basic认证给我选的话,我真的会选http basic认证。 不论是request.js的jar,或者file_get_content的set_headers,都很蛋疼。 |
52
avatasia 2015-01-13 19:52:40 +08:00
认证的话,每次都必须查询数据库,至于性能上的缓存,不是你们前端该操心的事情,老老实实用db查询。
还有如果是app的话,尽管实现session是没问题的, 但是现在谁还用这种老土的方式? 请google authorize token。 |
53
realityone 2015-01-13 20:22:47 +08:00
我设计的一般是登录成功就返回一个 token
后续靠 token 来操作 token 就存在 redis 里好了 |
54
DRcoding 2015-01-13 20:44:36 +08:00
像这种情况,如果不想查询数据库的话,客户端和服务端用Base64约定同一个加盐的方式验证就可以了,只要加盐方式不泄露的话。
|
55
jarlyyn 2015-01-13 21:08:55 +08:00
回家的路上边开车边想,其实楼主的做法有点坑啊。
首先session本身并不是一个缓存,session本身是有过期时间的token以及对应的数据,一般构建在缓存之上。以express为例,其实session本身是构建在mysql/nosql/redis/文件/内存上的,而不是缓存本身。php的话道理也一样。也就是说,session本身是一个需要缓存的东西,而非缓存。后期去用session实现缓存本质上是多次一举了,还要复出更大的代价,以及无法在别的需要缓存的地方复用。 再说客户端。如果要使用session, 那么必须要考虑过期,过期后需要用专门的接口认证,也就是基本上实现半个oauthtoken。那别人不用县城的oauth库,去使用session,不是自己和自己过不去啊。 |
56
yuankui OP @jarlyyn 我回家的路上也在想,确实比较坑。。
我原意是把session当做cache来用了。后来发现session过期之后客户端的操作更加繁琐。 现在我们本事不用oauth其实可以的,只要请求是通过https的就行。 |
57
winiex 2015-01-13 22:21:40 +08:00
刚开始设计 API 的时候就应该 RESTful 化,然后加上一个基于 Oauth 2.0 的验证机制,就不会出现类似的问题了。当然这个在你现在的情境下比较不现实。
如果是我的话,我会拉这个哥们一起喝点东西,然后请他按照更科学的方式来做。 |
58
shajiquan 2015-01-13 22:36:31 +08:00
你同事做的没什么问题,很常规的策略。他加缓存的话,会适当地减轻库的压力。但你们才刚开始,用的着加缓存么?加大开发量,增加复杂度。
验证这种事情,客户端只需要把 auth key 和 user id 之类的传上去,全部由服务端来处理就好了。客户端不需要搞这些。尤其是,未来单点登录多点登录之类的问题出现的时候,服务端调起来也更方便。 |
59
bolasblack 2015-01-13 23:07:24 +08:00 2
实话说,所有请求带上帐号密码最严重的问题并不是性能问题吧?最严重的是安全问题吧????
你们的 API 是 https 的嘛?没有的话人家随便截个包那用户的密码就暴露了呀,这是上个世纪的做法吧? 我简单看了一下,发现上面的人说的都不在点子上,这种做法,从根子上就有问题,完全就不应该这么干,就算解决了性能问题也不行 用个 token 怎么了?客户端能死啊?才加了多少难度啊,自己包装一个发起请求的函数然后在这个函数里加 token 有什么难度么?我就是做客户端的,我之前也有一个写服务端的同事像你那个同事那么干,我直接和他说这有问题 这不是经验与否的问题,如果他不是因为项目期限或者什么原因而不愿意改,在我看来,这是责任心的问题 至于解决方案,oAuth 2.0 稍微有点复杂了,建议使用 JWT ,介绍: http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/ 我有一个 repo 写了一些设计 API 时的建议,我推销一下: https://github.com/bolasblack/http-api-guide |
60
bolasblack 2015-01-13 23:08:13 +08:00
而且 JWT 协议本身也能实现类似缓存的功能
|
61
elvba 2015-01-13 23:34:08 +08:00
@bolasblack 赞成责任心是根本问题。
|
62
jarlyyn 2015-01-13 23:34:29 +08:00
|
63
zhicheng 2015-01-13 23:42:36 +08:00
@Jaylee
HTTP Basic 如果实现不好,非常容易被实施字典攻击。 不过不是说一个有问题,另一个就一定比这个好。 Token Base 的认证,很难实现正确,那些即使成为标准好多年的协议,依然可能有安全隐患。 |
64
bolasblack 2015-01-13 23:48:13 +08:00
@jarlyyn
* 一次请求和多次请求,你说哪个被截包拿到密码概率大? * token是有时限的,过了时限就无效了,不像密码 * 密码泄漏了以后可能会导致用户在别的网站上的帐号失守 * 你去看看国内有多少没有用 https 的网站,你再看看世界上有多少只有登录那一步用了 https 的网站,你再想想为什么会有这么一篇文章 https://raw.githubusercontent.com/citypw/citypw-SCFE/master/security/Documentation/ssl-tls_deployment_best_practices.txt |
65
yellowV2ex 2015-01-13 23:50:18 +08:00
第一次登陆的时候,会把密码加密一下,先MD5截取前10位,然后在用当前的时间和其他的什么key来到了后端再解密,可以防一些简单的抓包,App里会记录下来,下次打开的时候,自动登录。
其实用token,后端也是每次都要验证一下啊不是吗 简单的app会直接用session,不过有时候上传文件服务器会识别为一个新session就比较麻烦 |
66
cloudzhou 2015-01-14 00:33:22 +08:00
基本上,只要有人问 API 应该怎么设计,我就回去推荐 https://developer.github.com/v3/
在我看来,简直是教科书一般了,直接参照就可以了(这个不算抄袭) |
68
jarlyyn 2015-01-14 10:00:28 +08:00
@bolasblack
1.你的前提是建立在api访问没有使用独立密钥的情况下,所以,和https basic本身的有啥联系么…… 2.无法理解这个逻辑。有时限,所以泄露了也没不安全? 3.这个是是否发送明文密码的问题,和https basic本身有啥联系? 4.你讨论的是api还是网站?网站不做https很容易理解。api不用https不就是和登录不用https一个道理? 你也无法证明不使用https时,使用oauth/其他token方式是安全的。不是么? 或者说,你是想告诉大家,所有用帐号密码登录的网站都是不安全的?安全不是以最短的那个木板来决定的么? |
69
jarlyyn 2015-01-14 10:05:45 +08:00
@bolasblack
顺便提一下,github的api现在也依然保留着http basic验证吧…… curl -u <username> https://api.github.com/user。 虽然说存在即合理这句话的确有点操蛋。但以自己的需求去否决别人的需求,个人觉得,也有点操蛋的嫌疑。 |
70
bolasblack 2015-01-14 10:45:11 +08:00
@jarlyyn
* 第一条我没懂你在反驳我什么 * 我什么时候说“没不安全”了……有时限至少风险出现的时间是有限的(虽然危害是无限的) * basic auth 难道不是明文的么…… * 我说的第四条,目的是说,国内有很多 API 是根本没有部署 TLS,很多时候就算部署了 TLS,也不一定部署好了 盾永远都不是无懈可击的,盾的作用就是减少受伤的范围和概率 我说的不是需求,非 HTTPS 下明文传密码就是一个巨坑,是该直接杜绝的东西 当然,最好 HTTPS 下也不要明文传…… |
71
zjuster 2015-01-14 12:44:10 +08:00
技术方面不评论,从沟通上,你还要好好学学。
你上来的语气给人感觉就是打脸来的,而且自己很懂的样子——那位同事相比真的很克制了,很给你面子。(遇到不爽的,直接当场打回来让你下不了台。) 既然任务画好了圈子,你可以说这点的实现可能别的建议,但是别上来摆出“教”的姿势,更何况你自己也没有考虑充分。 不懂装懂是职场大忌讳,别给别人留下这样的印象;**不懂的事情就不要发言。** |
72
winiex 2015-01-14 12:57:02 +08:00
|
73
winiex 2015-01-14 13:04:12 +08:00
@jarlyyn
token 不像用户名、密码一样一暴露影响用户所有账户的安全,而且可以设置 token 的定期过期时间,过期了客户端自动拿着 refresh token 去换新 access token 就行了,然后再配合 token 的资源权限,哪里可以读,哪里可以写,一分钟内只能请求多少(throttle control),都可以做到比用户名、密码的认证机制灵活。严格地按照 OAuth 2.0 来实现,在 http 的情况下也是能够保证一定的安全性的。 当然,https 是必要条件。 |
74
winiex 2015-01-14 13:08:10 +08:00
完整的实现还会在 access token 的基础上加上一个带有时间戳因素的 timestamp hash string,每隔一段时间就变换,就算嗅探攻击拿到了 access token,你最多用了一段时间就没办法用了,因为你没办法知晓 timestamp hash string 在计算过程中用了哪些 magic number/salt,也不清楚其算法。
|
75
jarlyyn 2015-01-14 13:31:26 +08:00
@winiex
不需要和我解释token是什么,以及oauth的流程。 先不提很多实际应用中发送的并不是帐号和密码,而是在网站上设置的独立的key。 最基本的问题是。token是怎么来的?是否是在网上提交帐号和密码换取的? oauth的确有很多优势,但你并没有证明http basic验证就是一个不该使用的方式。 如果你觉得是,请给github发邮件抗议吧…… |
76
winiex 2015-01-14 13:53:02 +08:00
@jarlyyn
我同意你对于 HTTP Basic 的看法,从技术层面看是必须申请证书上 HTTPS 连接。 问题是国内很多项目在建立时基本就没有这个意识,作为单个程序员在后期加入后话语权过轻又无法改变,那该怎么办?这就是楼主面对的条件。那就只有尽量少传输用户名、密码,在 HTTP 上严谨地实现 OAuth 2.0 协议。 你的担心是技术上正义的,但在很多公司内往往不是现实上可行的。 |
77
zhicheng 2015-01-14 14:56:33 +08:00
@winiex
一个不幸的事实是,OAuth 2.0 如果不使用 HTTPS ,几乎和 HTTP Basic 一样不安全。 |
79
ioth 2015-01-14 16:12:55 +08:00
公司有多少名员工?
多少名开发人员? |
80
br00k 2015-01-14 18:12:21 +08:00
SSL+token
|
82
sampeng 2015-01-15 16:18:51 +08:00
加个cookie哪门子的增加客户端难度了。。我实在没想明白。。。
cookie的存在就是干这个事的。 |
83
sampeng 2015-01-15 16:26:06 +08:00 2
尤其是这种后端api端。
通用,简单的才是最好的。 现在是手机,以后可以是其他的端,什么逻辑都不用改,只要遵循http协议规范就能用api接口。 而,如果是get参数里面携带各种参数,每个接入进来的端都要根据逻辑来调整。一旦登陆需求变化,集体变化。oauth个人认为不是使用在内部系统里面的,纯属于多此一举,内部系统,纯粹的用户+密码就完事了。 简单可依赖啊。。 lz沟通我觉得。。。楼上有一楼说得对,压根没到点上面。。。和性能用啥关系。就算直接去查数据库。这么说吧,除非你是千万级用户。老老实实查db一点问题没有。大不了把用户库分离出来。都不需要加缓存。几十万用户,mysql抗起来轻轻松松的事。 |