目录
一.登陆注册 需求分析:
1)登陆之后,才能预约挂号:
2)登陆采取 弹出层的 形式:
3)登录方式:
a:手机号 + 验证码:
b:微信扫码登陆:
4)无注册界面:
a:登陆时,根据手机号判断是否存在该用户,不存在则自动注册:
5)微信扫描登陆成功后,必须绑定手机号:
a:即:第一次登陆,绑定手机号,以后登陆扫描直接登陆:
6)通过网关,统一判断登录状态,如需要登录则弹出登陆层。
二.登陆注册环境搭建:
1)创建微服务:server-user:
2)修改 application.yml:配置文件:
3)启动类:
4)配置网关:网关跳转到 server-user 服务:
5)添加用户基础类:
a:添加 用户基本信息 POJO 类:
b:Controller:
c: Service:
d:Mapper:
三. 手机登陆,基本实现
1)手机号登陆接口:
a:Controller:
b:Service:(也可以将 Token 存储到 redis)
2)整合 JWT 生成 token:
a:token 存储登录信息:(完成登陆后,生成字符串)
b:JWT 工具介绍:
c:JWT 组成:
d: 引入依赖:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
e:工具类:
public class JwtHelper {
//过期时间
private static long tokenExpiration = 24 * 60 * 60 * 1000;
//签名秘钥
private static String tokenSignKey = "123456";
//根据参数生成token
public static String createToken(Long userId, String userName) {
String token = Jwts.builder()
.setSubject("USER")
.setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))
.claim("userId", userId)
.claim("userName", userName)
.signWith(SignatureAlgorithm.HS512, tokenSignKey)
.compressWith(CompressionCodecs.GZIP)
.compact();
return token;
}
//根据token字符串得到用户id
public static Long getUserId(String token) {
if (StringUtils.isEmpty(token)) {
return null;
}
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
Claims claims = claimsJws.getBody();
Integer userId = (Integer) claims.get("userId");
return userId.longValue();
}
//根据token字符串得到用户名称
public static String getUserName(String token) {
if (StringUtils.isEmpty(token)) {
return "";
}
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
Claims claims = claimsJws.getBody();
return (String) claims.get("userName");
}
public static void main(String[] args) {
String token = JwtHelper.createToken(1L, "lucy");
System.out.println(token);
System.out.println(JwtHelper.getUserId(token));
System.out.println(JwtHelper.getUserName(token));
}
}
f:修改 原先业务:
3)整合 短信服务:(116-119)
a:发送验证码,将验证码存储到 Redis ,登陆时候进行验证。
4)前端整合
四.用户认证 与 网关 整合
1)思路:
2)思路:
a:所有请求,都要经过网关,经过网关,要先经过验证服务器,通过登陆验证后,在转发到 目标服务器:
3)实现:调整网关服务器
a:在服务网关添加 fillter:全局Filter,统一处理会员登录与外部不允许访问的服务
/**
* <p>
* 全局Filter,统一处理会员登录与外部不允许访问的服务
* </p>
*
* @author qy
* @since 2019-11-21
*/
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
private AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
System.out.println("==="+path);
//内部服务接口,不允许外部访问
if(antPathMatcher.match("/**/inner/**", path)) {
ServerHttpResponse response = exchange.getResponse();
return out(response, ResultCodeEnum.PERMISSION);
}
//api接口,异步请求,校验用户必须登录
if(antPathMatcher.match("/api/**/auth/**", path)) {
Long userId = this.getUserId(request);
if(StringUtils.isEmpty(userId)) {
ServerHttpResponse response = exchange.getResponse();
return out(response, ResultCodeEnum.LOGIN_AUTH);
}
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
/**
* api接口鉴权失败返回数据
* @param response
* @return
*/
private Mono<Void> out(ServerHttpResponse response, ResultCodeEnum resultCodeEnum) {
Result result = Result.build(null, resultCodeEnum);
byte[] bits = JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(bits);
//指定编码,否则在浏览器中会中文乱码
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
return response.writeWith(Mono.just(buffer));
}
/**
* 获取当前登录用户id
* @param request
* @return
*/
private Long getUserId(ServerHttpRequest request) {
String token = "";
List<String> tokenList = request.getHeaders().get("token");
if(null != tokenList) {
token = tokenList.get(0);
}
if(!StringUtils.isEmpty(token)) {
return JwtHelper.getUserId(token);
}
return null;
}
}
b:
c:
4)