V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  nothingistrue  ›  全部回复第 107 页 / 共 109 页
回复总数  2174
1 ... 99  100  101  102  103  104  105  106  107  108 ... 109  
2022-04-21 14:22:40 +08:00
回复了 SSang 创建的主题 程序员 长期的用户令牌是如何存储的呢?存储结构是什么样的?
@qiany 说个简单的场景,就用户名、密码、JWT 、自动登录这几个元素。
1.1 、第一次登录,客户端发送用户名、密码;
1.2 、服务器根据存储的用户名,密码做比对来验证(密码是散列码或者密文保存,这个不在这里讨论);
1.3 、验证通过后,服务器生成 JWT 令牌,返回给客户端;
1.4 、客户端保存这个 JWT 令牌;

到此,登录认证阶段结束。

2.1 、所有必须需要先登录的接口,在请求时都要带上这个 JWT 令牌;
2.2 、服务器尝试解码这个 JWT 令牌,如果能解码,就算认证通过,否则返回认证失败;
2.3 、(可选的授权认证,这玩意后台管理系统用得多,普通系统一般不用) JWT 令牌通常都会包含用户主键,服务器那这个主键,去查找这个用户的授权,跟当前的操作需要的授权,做对比,验证当前用户是否允许这个操作;

到此,后续认证及授权阶段结束。因为除了登录、注册以及其他不需要登录就能访问的接口,都要做后续认证,这样自动登录就没必要做了,或者说上面的后续认证,就是自动登录。

上面的过程中,生成和解析 JWT 令牌,需要一个密钥,这个要服务器保存下来。通常(不是超高安全级别要求),整个系统就使用一个密钥,这个密钥直接放配置文件就行,不需要放数据库。服务器不会保存 JWT 令牌,这个客户端自己保存就够了。用户名密码这种验证是一种验证方式,令牌使用的是另外的验证方式,不一样(具体的我也不太清除,有兴趣的话你可以再查查)。


至于额外的控制,还拿上面的场景说。令牌是明文的,如果只是上面的处理,攻击者只要能够截取到这个令牌(或者攻击客户端读取到这个令牌),它就可以用这个令牌模仿对应用户的访问。所以当认证要求高的时候,就不能只认令牌,需要其他信息来辅助认证。对于敏感操作,应当直接不认这个令牌,要让用户重新登录,然后回到传统的 Session 认证。普通访问,也可以检测当前客户端的 IP 所在地,如果不在用户经常登录所在地(这个信息要保存到缓存)当中,就也不认这个令牌,让客户端重新登录。如果客户端是手机 APP ,还可以在令牌中保存 APP 的唯一识别信息,然后每次认证时都对比令牌中的唯一识别信息跟实际的信息是否相符来做辅助认证(不过这个只防君子不防小人,因为能伪造令牌就能伪造唯一识别信息)。
2022-04-21 10:45:34 +08:00
回复了 SSang 创建的主题 程序员 长期的用户令牌是如何存储的呢?存储结构是什么样的?
你把登录认证跟后续认证当成一会事看才会产生那么多问题,但这俩有区别。在技术上它俩确实是一回事,都是做身份认证的,但是使用场景上不一样。

登录认证,是用于用户 /客户端接入系统的第一道认证,它面向的是完全未知的用户 /客户端,所以要做高级别的校验——用户名+密码、两部认证、动态令牌,直到最高级别的物理令牌。

静态令牌认证,即你现在说的这种令牌,这是后续认证。后续认证是不能单独存在的,它必然要依附于登录认证,所以它可以做低级别的验证——比如只要有用户 ID 就放行。因为验证级别很低,服务器甚至都不用保存它,单靠实时算法就可以验证它的真假。(静态令牌认证里面可能会带昵称、日期等杂七杂八的信息,这些是为了使用方便,不是做认证用的)

比如说卧铺检票,只有上车的时候才会检查车票,这时候它会收走你的车票把它换成卧铺专票——随便打印一下没啥防伪措施的票,后面就只查这个专票,不查车票了。

有了上面的区别就好解释了,静态令牌因为是后续认证,它只需要一个用户主键就能完整验证,不需要密码等敏感信息,也不需要存储。同时,你不能完全相信静态令牌,不管是短期还是长期的,你都要在服务器端做额外的控制。

你的方法一,不存在。那就是用户名密码,token 是画蛇添足。你应该再看看 JWT 的用法,JWT 场景下服务器是不存令牌的,它只配置一个全局使用的密钥。JWT 的安全级别也不高,就相当于一个不能伪造的用户主键,当然这是为了自动登录方便的后续认证,这样用没问题。JWT 有不少安全问题,但那本来就不是 JWT 该解决的问题。

你的方法二,它怎么存储的并不重要,因为这个 token 跟 JWT 一样,就是代表用户主键,服务器从这个 TOKEN 解析出来用户主键之后,再拿用户主键去做后面的授权认证(这里你把认证跟授权也搞成一回事了,这也是两码事)。至于安全性吗,你这里举例得场景是 git push ,这玩意真得没啥安全要求,PR/MR 外加保护主分支,普通分支阿猫阿狗随便 push 都没事,哪怕 push -force 覆盖了以前的内容,git 的分布式外加 Github 的备份措施,也能给恢复过来。说直白点,Github 的用户令牌丢了,最多就是丢脸,没啥卵影响。
开源还是私有,有 devops 还是没有 devops ,有运维还是没有运维,这些会影响你的选择。

下面是我的经验,具体还要靠你们的运维或 devops 管理去做评估。

开源的话,至少要 Github ,最好是以 Github 为主,码云为镜像。
私有的话,如果只是仓库、Issue 库、Wiki 库,没有 devops ,那么首选自建(你们人少,Gitea/Gogs 就足够,人多就要上 Gitlab 了)。
如果是私有并且还要 Devops ,钱多就上 Github 企业版、Gitlab 企业版,或者微软那个开发平台(个人想法,建议 Gitlab 企业版,Github 有些规则,比如没有变基合并 /准线性历史,很反人类),钱少但是有运维的话开源让运维搞 Gitea+Jenkins (这个懂 Docker 就能搞)
@lmshl 你把响应式处理 /流式处理,跟 NIO 搞混了吧。
@liuhan907 @lmshl 异步跟单线程不冲突,用线程池处理异步是 Java 的专用方式,其他语言处理异步不是用的线程池。
@lmshl 客户端应用读取一个文件准备编辑,说直白点就是记事本,这你也要用 NIO 去读取文件吗。虽然 Java 桌面应用很拉跨,但你也不能假定 Java 就只是搞 Web 服务器或者大型计算的,有些场景就是简简单单的线性同步处理,这时候你用 NIO 那就是杀鸡用牛刀。

@jeesk 同步异步这里我草率了,NIO 是确实是同步非阻塞的。NIO 跟 BIO 区别的是任务切换的效率,跟同步异步没多大关系,BIO 也能做异步。他俩用哪个,主要还得看并发。
发现楼上有些人是 “nio 优于 bio”,或者 “nio 要替代 bio” 的想法,这是不正确的。NIO 异步非阻塞,BIO 同步阻塞,这俩是应对不同场景的,不是不考虑场景就无脑用一个。如果是客户端应用读取一个文件准备编辑的场景,用 NIO 就是个沙雕(这里 UI 那里可以将读取文件的过程作为子过程异步调用,但读取文件这个过程,单线程阻塞是最优解)。

还有异步同步也是要分场景的,并且异步本身,也是分为全异步的 callback 模式跟异步同步结合的 async/await 模式。无脑异步,或者无脑 callback ,也是沙雕行为。

楼主是上面看法的反方,是错的,但不代表上面看法的正方就是对的。楼主的标题说的是很正确的,互联网上的很多知识都会带入非黑即白的世界观,这才是最大的误导。
还有,NIO 200 个线程是应对五万并发连接的(一个 Linux 单机最高就能开这么多连接,没这个限制它能应对更多),实际上压根也用不到 200 个线程,物联网或者没有文件上传下载场景的接口服务器场景下,10 个线程就能轻松应对五万并发连接。请注意这里的并发连接是指可以毫秒级别同时响应的连接。

后面你提到 RPC 大多用 NETTY ,那是因为 RPC 服务器是至少上千通常上万的并发量(没到这个并发量也没必要开 RPC )。
你的标题是对的,但你下面说得谬论好些不是谬论。

1. 抛开剂量来说影响,那是耍流氓,线程切换的消耗跟线程的数量,是指数对比,200 个线程你看不出来区别,但是一千一万呢,不要说物联网服务器,就是面向公众的普通 Web 服务,那都是一万起步的。

2. 请参见一,在 tomcat 改成 NIO 之前,它要么只应用在不到百人的企业内部,要么躲在 IIS/Apache 后面,压根不会直接面向公众(早期确实有不负责任的人那 tomcat 当前台服务器的页游,那响应速度是相当感人的)。

3. 这么貌似确实是谬论,我也没看懂。Netty 本质上只是对 Java nio 的易用性封装,并没有动 NIO 的原理。至于你的阻塞疑问,IO ,不管是本地 IO 还是网络 IO ,并不是总是在传输的,他经常是在等待输入源 /输出目的可用的等待过程,这期间它是不工作的,这个时候,如果是 BIO ,不管是否工作它都要占用线程,如果是 NIO ,不工作期间是不占用线程的。
2022-04-18 12:20:29 +08:00
回复了 catcardriver 创建的主题 程序员 大厂的 iOS 开发可以转 Java 开发好吗?
IOS 、Andorid 、TypeScript 、C#/Xamain/WinForm ,这几个是平滑切换的,切换起来基本只需要转换细节性的习惯,不过前提是至少吃透了 1 个。你只有 1 年经验,IOS 很难吃透,这样没有转换的可能性,基本都是重来,所以不到万不得已或者确实不想搞 IOS 了,不要转。

如果是向往 Java 后端走,那就跨行了,这个没啥固定评价,主要靠你面试之后自我评估。
2022-04-15 12:12:18 +08:00
回复了 nanvon 创建的主题 Android 有没有能够强制 [自动锁屏] 的软件?
正常途径下,没有。亮屏设置当中,前台应用的设置具有最高优先级。系统不会打扰前台应用的亮屏设置,更不会允许外部应用干扰当前应用的亮屏设置。

正常途径,也好解决,向 APP 反馈让可以自定义亮屏设置。这个改动不难,如果不改,那就是流氓应用,卸载对待。
2022-04-11 13:39:10 +08:00
回复了 Aliberter 创建的主题 程序员 Java 字符串替换的问题
旁观者轻:#XXXXX#替换为 aXXXXXa ,跟#替换成 a ,没有区别。
实际寿命通常是售后期限的两倍,智能手机售后都是一年。一般两年以后的大版本更新,基本上仅取决于自动测试的结果,那是绝对不会专门安排人去负责更新的。苹果能更新好几年,那是因为 IOS 系统基本不大动——光 UI 风格都能好几个大版本一样就更别提底层引擎了。三棒能升级三年,那也是因为 Android 现在的系统本质上都是 8.X 。(当然总归是要变一些的,所以那些老手机升级后,因为只经过自动测试没经过人工调配,大概率要变差。)
2022-04-08 12:58:21 +08:00
回复了 shawnwang340 创建的主题 程序员 Java 开发者面向对象编程?不不不,是面向 Spring 编程
还是见得少,Oracle 的一部分、Mysql/MariaDB 、Handop 体系、Apache Storm 等等工具类的应用,这些也是 Java 开发的,他们不用 Spring 。只能说业务类或信息处理类的应用(以前还有专有名词 Java EE——Java 企业级应用),绝大部分都是用 Spring 体系的。
2022-04-08 09:16:52 +08:00
回复了 twofox 创建的主题 Java Controller 和 Service 中注入 HttpServletResponse 有什么差异吗
@codergrowing #15 可能我记错了,不过 Spring Boot 之后,Spring MVC 部分推荐的都是通过方法参数注入,已经基本不用成员变量注入了,这种注入单例非单例都没区别。一般来说,从 Struts2 之后,控制器部分都是单例的,可能 Spring MVC 发现没有成员变量注入之后会自动优化成单例模式。
2022-04-07 16:27:03 +08:00
回复了 twofox 创建的主题 Java Controller 和 Service 中注入 HttpServletResponse 有什么差异吗
你的第二次使用已经正确了:注入到 Controller ,再传递给 Service 。Controller 是非单例的有状态 Bean ,可以注入 HttpServletResponse 。 @twofox

其实对于 HttpServletResponse 这种跟当前请求绑定的对象,最好全程通过方法参数注入,不要将他注入到类的成员变量上。Spring MVC 中,如果把 HttpServletResponse 作为 Controller 的方法的参数,不需要加 Autowired 它都是自动注入的。
2022-04-07 13:46:05 +08:00
回复了 twofox 创建的主题 Java Controller 和 Service 中注入 HttpServletResponse 有什么差异吗
HttpServletResponse 是绑定当前连接的有状态对象,Service 通常是无状态 Bean ,Controller 通常是( Spring MVC 就绝对是)有状态 Bean ,因此,HttpServletResponse 注入 Controller (的成员)没问题,注入 Service (的成员)会产生严重问题。

你如果注入 Service ,那么第一个请求来了会把当前请求的 HttpServletResponse 注入单例的 Service 。单例的 Service 中的这个成员,一旦注入过就不会再重新注入了,以后所有的请求调用的 Service ,使用的都是第一个请求的 HttpServletResponse 。这个 HttpServletResponse 对象本身因为还被引用着不会被回收,但它里面引用的其他对象,会在第一个请求完成之后就销毁,于是后面就会出现 NullPointException 。


最后说一点,exportSevice.export(params, response) 这样的方法,即把依赖对象通过方法参数传入,不是用 Spring 实现的依赖注入,但它也是依赖注入。
2022-04-07 09:34:00 +08:00
回复了 Kawa 创建的主题 程序员 我想自己写一个前后分离的 UWP QQ, 遇到了一些问题
@Kawa 你对跨平台(或者操作系统适配)、UWP (通用应用)、客户端的理解都有偏差,然而最直接的还是太迷信 go 。go 最开始以及现在一直是用来替代 C 的,也许还能替代 C++,这意味着它跟 C/C++一样主要是用来适配 Windows 、Linux 、Unix 等传统操作系统的,不适配 IOS 、Android 、WebOS 、Win10 mobile 这样的新型移动操作系统(并不是不能适配,而是生态不在这里很少有人去吃力不讨好的搞底层适配库)。

win10 mobile 跟 win10 只是内核一样,整体上还是俩类型的操作系统。kindle 和早期 Android 系统,你解锁了之后就是个 Linux 。

其实你有更好的方案:PWA 。然后你就会发现真正的难点是跟 QQ 服务器做沟通——理论上来说,任何接入 QQ 服务器的第三方,都要被南山法院锤。
2022-04-06 17:36:18 +08:00
回复了 Ds97 创建的主题 程序员 验证短信码被盗刷怎么办
@Ds97 #19 国外手机号上 Google Recaptcha 或者其他机器人识别,国内手机号用他说的微信那个方法。
2022-04-06 17:30:04 +08:00
回复了 rock123 创建的主题 Java Java 如何监测静态变量值的变化?
逐步骤监控变量的值还有办法,但是你想在值变化时做自动处理(打印些信息),你不动代码是不行的。这是个 public 成员,可以直接赋值,切面都加不上。

还是想办法做断点调试吧,一步一步的查看值的变化。当然你不能直接在线上搞远程调试,尤其是你还想长时间的监控。你这个是公共静态变量,一个断点暂停就可能让整个系统崩溃。能在本地环境复现问题然后在本地断点调试是最好的,如果不能或者不好复现,那么只能逐行看代码了。

Eclipse 有几个功能可以帮助你找到哪个代码会修改这个值:右键变量然后选择“call hierarchy”;选中变量再 Ctrl+H ,然后可以查找所有引用这个变量的地方。
1 ... 99  100  101  102  103  104  105  106  107  108 ... 109  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2522 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 41ms · UTC 04:29 · PVG 12:29 · LAX 20:29 · JFK 23:29
Developed with CodeLauncher
♥ Do have faith in what you're doing.