18-认证接口开发-接口开发-service

4.3.4 Dao

暂时使用静态数据,待用户登录调通再连接数据库校验用户信息。

4.3.5 Service

调用认证服务申请令牌,并将令牌存储到 redis。
1、AuthToken
创建 AuthToken模型类,存储申请的令牌,包括身份令牌、刷新令牌、jwt令牌
身份令牌:用于校验用户是否认证
刷新令牌:jwt令牌快过期时执行刷新令牌
jwt令牌:用于授权

@Data
@ToString
@NoArgsConstructor
public class AuthToken {
String access_token;//身份token
String refresh_token;//刷新token
String jwt_token;//jwt令牌
}

在这里插入图片描述

申请令牌的service方法如下:

@Service
public class AuthService {
private static final Logger LOGGER = LoggerFactory.getLogger(AuthService.class);
@Value("${auth.tokenValiditySeconds}")
int tokenValiditySeconds;
@Autowired
RestTemplate restTemplate;
@Autowired
LoadBalancerClient loadBalancerClient;
@Autowired
StringRedisTemplate stringRedisTemplate;
//认证方法
public AuthToken login(String username,String password,String clientId,String clientSecret){
//申请令牌
AuthToken authToken = applyToken(username,password,clientId, clientSecret);
if(authToken == null){
ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);
}
//将 token存储到redis
String access_token = authToken.getAccess_token();
String content = JSON.toJSONString(authToken);
boolean saveTokenResult = saveToken(access_token, content, tokenValiditySeconds);
if(!saveTokenResult){
ExceptionCast.cast(AuthCode.AUTH_LOGIN_TOKEN_SAVEFAIL);
}
return authToken;
}
//存储令牌到redis
private boolean saveToken(String access_token,String content,long ttl){
//令牌名称
String name = "user_token:" + access_token;
//保存到令牌到redis
stringRedisTemplate.boundValueOps(name).set(content,ttl, TimeUnit.SECONDS);
//获取过期时间
Long expire = stringRedisTemplate.getExpire(name);
return expire>0;
}
//认证方法
private AuthToken applyToken(String username,String password,String clientId,String
clientSecret){
//选中认证服务的地址
ServiceInstance serviceInstance =
loadBalancerClient.choose(XcServiceList.XC_SERVICE_UCENTER_AUTH);
if (serviceInstance == null) {
LOGGER.error("choose an auth instance fail");
ExceptionCast.cast(AuthCode.AUTH_LOGIN_AUTHSERVER_NOTFOUND);
}
//获取令牌的url
String path = serviceInstance.getUri().toString()+"/auth/oauth/token";
//定义body
MultiValueMap<String,String> formData = new LinkedMultiValueMap<>();
//授权方式
formData.add("grant_type", "password");
//账号
formData.add("username",username);
//密码
formData.add("password", password);
//定义头
MultiValueMap<String,String> header = new LinkedMultiValueMap<>();
header.add("Authorization", httpbasic(clientId,clientSecret));
//指定 restTemplate当遇到400或401响应时候也不要抛出异常,也要正常返回值
restTemplate.setErrorHandler(new DefaultResponseErrorHandler(){
@Override
public void handleError(ClientHttpResponse response) throws IOException {
//当响应的值为400或401时候也要正常响应,不要抛出异常
if(response.getRawStatusCode()!=400 && response.getRawStatusCode()!=401){
super.handleError(response);
}
}
});
Map map = null;
try {
//http请求spring security的申请令牌接口
ResponseEntity<Map> mapResponseEntity = restTemplate.exchange(path, HttpMethod.POST,
new HttpEntity<MultiValueMap<String, String>>(formData, header), Map.class);
map = mapResponseEntity.getBody();
} catch (RestClientException e) {
e.printStackTrace();
LOGGER.error("request oauth_token_password error: {}",e.getMessage());
e.printStackTrace();
ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);
}
if(map == null ||
map.get("access_token") == null ||
map.get("refresh_token") == null ||
map.get("jti") == null){//jti是jwt令牌的唯一标识作为用户身份令牌
ExceptionCast.cast(AuthCode.AUTH_LOGIN_APPLYTOKEN_FAIL);
}
AuthToken authToken = new AuthToken();
//访问令牌(jwt)
String jwt_token = (String) map.get("access_token");
//刷新令牌(jwt)
String refresh_token = (String) map.get("refresh_token");
//jti,作为用户的身份标识
String access_token = (String) map.get("jti");
authToken.setJwt_token(jwt_token);
authToken.setAccess_token(access_token);
authToken.setRefresh_token(refresh_token);
return authToken;
}
//获取httpbasic认证串
private String httpbasic(String clientId,String clientSecret){
//将客户端id和客户端密码拼接,按“客户端id:客户端密码”
String string = clientId+":"+clientSecret;
//进行base64编码
byte[] encode = Base64.encode(string.getBytes());
return "Basic "+new String(encode);
}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.3.6 Controller

AuthController代码如下:

@RestController
@RequestMapping("/")
public class AuthController implements AuthControllerApi {

    @Value("${auth.clientId}")
    String clientId;
    @Value("${auth.clientSecret}")
    String clientSecret;
    @Value("${auth.cookieDomain}")
    String cookieDomain;
    @Value("${auth.cookieMaxAge}")
    int cookieMaxAge;

    @Autowired
    AuthService authService;

    @Override
    @PostMapping("/userlogin")
    public LoginResult login(LoginRequest loginRequest) {
        if(loginRequest == null || StringUtils.isEmpty(loginRequest.getUsername())){
            ExceptionCast.cast(AuthCode.AUTH_USERNAME_NONE);
        }
        if(loginRequest == null || StringUtils.isEmpty(loginRequest.getPassword())){
            ExceptionCast.cast(AuthCode.AUTH_PASSWORD_NONE);
        }
        //账号
        String username = loginRequest.getUsername();
        //密码
        String password = loginRequest.getPassword();

        //申请令牌
        AuthToken authToken =  authService.login(username,password,clientId,clientSecret);

        //用户身份令牌
        String access_token = authToken.getAccess_token();
        //将令牌存储到cookie
        this.saveCookie(access_token);

        return new LoginResult(CommonCode.SUCCESS,access_token);
    }

    //将令牌存储到cookie
    private void saveCookie(String token){

        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        //HttpServletResponse response,String domain,String path, String name, String value, int maxAge,boolean httpOnly
        CookieUtil.addCookie(response,cookieDomain,"/","uid",token,cookieMaxAge,false);

    }

    @Override
    public ResponseResult logout() {
        return null;
    }

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值