(一) 集群环境下如何解决登陆问题
如果不处理的话,Session是不能共享的,如果用户请求被Nginx轮询到不同的机器上的话,因为机器上session没有用户信息的话,就让重新登录,假如说这次nginx负载到了Tomcat1上, 那么就得登录一下, 下回nginx负载到了Tomcat2上,那么因为session默认是不能跨机器共享的,所以又得重新登录一下.
1.解决方式
方式1 nginx
nginx的ip hash 算法 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
缺点:不能充分考虑到各个服务器的性能,有可能同一时刻访问通过ip_hash出来都请求到一台服务器上,而且这台服务器的性能不行???
方式2, 用Redis代替session
Oauth2的四种授权模式
(一)什么是一个Oauth2协议
OAuth(开放授权)是一个开放标准,允许用户(你)授权第三方应用(王者农药)访问用户存储在另外的服务提供者(QQ服务器)上的信息,而不需要将用户名和密码提供给第三方移动应用(王者农药)这个就是典型的授权码模式。
1.密码模式
适用的业务场景 客户端应用(手机app) 是高度受信用的,一般是自己公司开发的app项目。
密码模式,认证服务器是自己内部的服务器.
2.授权码模式
授权码模式(最安全的模式) 业务场景 第三方不授信的,搭建自己的开发能力平台。
①:获取授权码http://localhost:9999/oauth/authorize?
response_type=code&client_id=portal_app&redirect_uri=http://www.baidu.com&state=abc
参数说明: client_id 认证服务器分配给第三方客户端的appid
response_type:固定格式 值位code
redirect_uri: 用户在认证服务器上登陆成功了 需要回调到 客户端应用上
state: 你传什么给授权服务器 授权服务器原封不动的返回给你
2:获取到code,去换取token
http://localhost:9999/oauth/token(Post请求)
3.简化模式(开发几乎不用)
开发中几乎接触不到 适用于 客户端就是一堆js css html 没有前端服务器
4.客户端模式(开发几乎不用)
动手搭建微服务认证中心实现微服务鉴权(不实用)
(一)基于内存的操作
案例:ZJJ_SpringCloud_alibaba_2020/06/16_19:55:55_bau11 |
---|
启动项目给yml的配置
flag: memory # flag设置成memory
1.密码模式访问
post请求 http://localhost:9999/oauth/token
2.授权码模式访问
http://localhost:9999/oauth/authorize?
response_type=code&client_id=portal_app&redirect_uri=http://www.baidu.com&state=abc
上面参数直接浏览器访问,然后就会重定向到http://www.baidu.com
重定向携带了state值
https://www.baidu.com/?error=access_denied&error_description=User%20denied%20access&state=abc
参数说明
client_id 认证服务器分配给第三方客户端的appid
response_type:固定格式 值位code
redirect_uri: 用户在认证服务器上登陆成功了 需要回调到 客户端应用上,你传递的要和后台设置的redirectUris那里去匹配
state: 你传什么给授权服务器,授权服务器原封不动的返回给你
get请求 http://localhost:9999/login
直接输入用户名和密码 用户名是zhangsan 密码是 123456
获取到code,去换取token
http://localhost:9999/oauth/token(Post请求)
redirect_uri 是 和配置的回调地址要一模一样
grant_type 是固定写死的
code 是从认证那里登录成功返回给你的code
尝试访问别的微服务
案例:ZJJ_SpringCloud_alibaba_2020/06/16_20:06:58_gn5tv |
---|
启动这个微服务, 然后用授权码模式获取的access_token 去访问这个服务
post请求:
http://localhost:8080/order/selectOrderInfoById/1
请求头 Authorization 携带 bearer xxxxxxxxxx 这个xxxxxx就是access_token
就能访问成功了. 注意Authorization 的type不要写
(二)基于数据库和redis的模式
1.授权码模式
案例:ZJJ_SpringCloud_alibaba_2020/06/16_19:55:55_bau11 |
---|
项目yml配置 切换db模式
flag: db # memory是内存模式 , db 是数据库模式 |
---|
修改oauth_client_details表的配置信息
直接发起get请求,注意redirect_uri参数需要和数据库oauth_client_details里面的配置一样才行.
http://localhost:9999/oauth/authorize?
response_type=code&client_id=portal_app&redirect_uri=http://www.baidu.com&state=abc
get请求 http://localhost:9999/login
直接输入用户名和密码 用户名是zhangsan 密码是 123456
获取到code,去换取token
http://localhost:9999/oauth/token(Post请求)
redirect_uri 是 和配置的回调地址要一模一样
grant_type 是固定写死的
code 是从认证那里登录成功返回给你的code
尝试访问别的微服务
案例:ZJJ_SpringCloud_alibaba_2020/06/16_20:06:58_gn5tv |
---|
启动这个微服务, 然后用授权码模式获取的access_token 去访问这个服务
post请求:
http://localhost:8080/order/selectOrderInfoById/1
请求头 Authorization 携带 bearer xxxxxxxxxx 这个xxxxxx就是access_token
就能访问成功了. 注意Authorization 的type不要写
Gateway实现Oauth2
我们的微服务不再做权限控制,把权限控制功能放到网关上.
用户通过浏览器 携带clientId 等等信息请求token, 网关直接转发请求token的资源给认证中心, 然后返回token.
用户通过浏览器访问服务的时候,会携带token,token在网关那里进行校验,校验通过就访问指定的服务,校验失败就提示前端权限不足.
1.jwt模式
案例:ZJJ_SpringCloud_alibaba_2020/06/17_12:28:06_3ihi7 |
---|
启动好项目之后开始测试:
访问
http://localhost:8888/oauth/token
就能获取到结果
测试token是否好用
启动sso-product-jwt-server项目
Authorization用上面的access_token
访问成功是这个,如果访问失败的话就会抛出异常出来.