1.搭建前端app
以黑马头条前端为例,由于其使用了子conf文件,需要子conf目录,所以需要修改原有的nginx的docker-compose文件,原来的文件指定了conf文件的映射,但并没有指定子目录的映射,因此直接新建一个子conf目录是不会映射的。所以需要对目录进行映射,但映射目录后,原有的mine.types文件又会失效,所以需要创建该文件的映射,最终的nginx-web修改如下:
nginx-web:
image: nginx:1.21.6
container_name: nginx-web
environment:
# 时区上海
TZ: Asia/Shanghai
ports:
- "80:80"
- "443:443"
volumes:
# 证书映射
- /docker/nginx/cert:/etc/nginx/cert
#mime.types
- /docker/nginx/mime.types:/etc/nginx/mime.types
# 配置文件映射
- /docker/nginx/conf/confs:/etc/nginx/confs
# 配置文件映射
- /docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
# 页面目录
- /docker/nginx/html:/usr/share/nginx/html
# 日志目录
- /docker/nginx/log:/var/log/nginx
privileged: true
network_mode: "host"
删除原有nginx容器,重新执行
docker-compose up -d nginx-web
黑马头条前端配置如下:
heima-leadnews-app.conf
upstream heima-app-gateway {
server 192.168.0.105:8080;
}
server {
listen 8801;
location / {
root /usr/share/nginx/html/app-web/;
index index.html;
}
location ~/app/(.*) {
proxy_pass http://heima-app-gateway/$1;
proxy_set_header HOST $host; # 不改变源请求头的值
proxy_pass_request_body on; #开启获取请求体
proxy_pass_request_headers on; #开启获取请求头
proxy_set_header X-Real-IP $remote_addr; # 记录真实发出请求的客户端IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #记录代理信息
}
}
nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 引入自定义配置文件
include confs/*.conf;
}
把app-web目录拷贝到html下,整体目录结构如下:
重新启动容器后,访问192.168.0.80:8801
2.创建user微服务
1.准备工作
需要在ruoyi-common下创建两个模块:
ruoyi-common-utils
ruoyi-common-model
直接从下方网盘地址复制即可。
链接:https://pan.baidu.com/s/1a15irP_BpdHFSNWabA8m0A
提取码:1111
其中,model中存放了user的dto类以及返回值包装类ResponseResult。
dto就是类似若依里的bo,在这里可以简单理解为前端访问后端的参数对象,业务对象(Business Object,BO)与数据传输对象(Data Transger Object, DTO),只不过dto只负责传递数据,bo中带有了行为–若依中体现为验证行为,随便找一个bo看一看:
utils中存放了原版教程中的jwt生成依赖类AppJwtUtil。注意,由于ruoyi系统的jdk版本我选用了jdk11版本,所以utils中的Base64Utils类依赖的sun.misc已经不存在了,我直接从jdk7中把对应的sun.misc源码拷贝了过来:
切记!在ruoyi-common的ruoyi-common-bom模块中的pom.xml文件中定义好新增的两个模块的版本,这样引用的时候就不用加版本号了:
2.创建微服务
在ruoyi-modules中创建ruoyi-user微服务,完整目录如下:
具体源码可以从这里拷贝:
直接从下方网盘地址复制即可。
链接:https://pan.baidu.com/s/1a15irP_BpdHFSNWabA8m0A
提取码:1111
3.配置文件
添加多数据源
nacos中的datasource.yml里,添加user服务的数据库配置:
user:
url: jdbc:mysql://192.168.0.80:3306/ry_news_user?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
username: root
password: root
创建ruoyi-user.yml,内容为(注意多数据源配置时对应的user参数,不要写错了):
spring:
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为 master
primary: master
datasource:
# 主库数据源
master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${datasource.user.url}
username: ${datasource.user.username}
password: ${datasource.user.password}
seata配置
由于引入了seata依赖,如果不需要可以删除。不删除则需要配置该微服务加入seata组,由seata进行分布式事物的监管。
seata-server.properties中:
规范为:微服务名-group即可。
service.vgroupMapping.微服务名-group=default
4.核心代码
pom.xml中引入了satoken,目的是使用若依内置的给予satoken权限管理框架系统实现前端app登录
ApUserServiceImpl中替换原有的密码比对方式,由原来的md5+salt,换成BCrypt
正因如此,数据库设计也发生了一点变化:
去掉了salt字段,bcrypt会自动生成,并且增加了password的长度:
密码也做了替换:admin123
加盐后:
$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2
通过我新写的LoginHelper.login4News方法,实现了用户登录以及token的返回,按照原需求,如果用户正常登录,则返回通过用户id创建的token,如果用户未登录选择“先看看”,则返回以用户id为0生成的token:
由于前端没有注册的业务需求,所以这里只给用户存放了id和登录类型,在若依中,登录类型分为app_user和pc_user。
public static String login4News(int loginId, DeviceType deviceType) {
LoginUser loginUser = new LoginUser();
loginUser.setUserId(Long.valueOf(loginId));
loginUser.setUserType("app_user");
SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
StpUtil.login(loginUser.getLoginId(), deviceType.getDevice());
setLoginUser(loginUser);
return StpUtil.getTokenValue();
}
UserActionListener
用户登录成功后会触发,丰富用户信息,如登录ip,时间等等,连同token一起存入redis中
else if (userType == UserType.APP_USER) {
// app端 自行根据业务编写
System.out.println("进入app端登录判定!");
UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = ServletUtils.getClientIP();
LoginUser user = LoginHelper.getLoginUser();
SysUserOnline userOnline = new SysUserOnline();
userOnline.setIpaddr(ip);
userOnline.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
userOnline.setBrowser(userAgent.getBrowser().getName());
userOnline.setOs(userAgent.getOs().getName());
userOnline.setLoginTime(System.currentTimeMillis());
userOnline.setTokenId(tokenValue);
userOnline.setUserName("");
if (ObjectUtil.isNotNull(user.getDeptName())) {
userOnline.setDeptName(user.getDeptName());
}
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline, Duration.ofSeconds(tokenConfig.getTimeout()));
log.info("user doLogin, useId:{}, token:{}", loginId, tokenValue);
}
其他操作和原教程一致
3.配置gateway
1.增加白名单
- /**/user/api/v1/login/login_auth/
2.添加路由配置
- id: ruoyi-wemedia
uri: lb://ruoyi-wemedia
predicates:
- Path=/wemedia/**
filters:
- StripPrefix=1
4.修改satoken配置
经过测试,前端app传递的token方式和后端不同:没有添加前缀,并且存放在cookie中。所以这里需要修改,注释掉前缀,并且把通过cookie取得token改为true:
5.测试
http://192.168.0.80:8801/
分别使用输入用户名密码登录以及直接点击“不登录,先看看”
会跳转到article页面,其中的network显示已经在cookie中存入了生成的token:
reids中可以看到两种不同登录方式都被成功储存:
大功告成!