package com.leon.oauth.controller;
import com.leon.oauth.service.LoginService;
import com.leon.oauth.util.AuthToken;
import com.leon.oauth.util.CookieUtil;
import entity.Result;
import entity.StatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* 描述
*
* @author www.leon.com
* @version 1.0
* @package com.leon.oauth.controller *
* @since 1.0
*/
@RestController
@RequestMapping("/user")
public class UserLoginController {
@Autowired
private LoginService loginService;
@Value("${auth.clientId}")
private String clientId;
@Value("${auth.clientSecret}")
private String clientSecret;
private static final String GRAND_TYPE = "password";//授权模式 密码模式
@Value("${auth.cookieDomain}")
private String cookieDomain;
//Cookie生命周期
@Value("${auth.cookieMaxAge}")
private int cookieMaxAge;
/**
* 密码模式 认证.
*
* @param username
* @param password
* @return
*/
@RequestMapping("/login")
public Result<Map> login(String username, String password) {
//登录 之后生成令牌的数据返回
AuthToken authToken = loginService.login(username, password, clientId, clientSecret, GRAND_TYPE);
//设置到cookie中
saveCookie(authToken.getAccessToken());
return new Result<>(true, StatusCode.OK,"令牌生成成功",authToken);
}
private void saveCookie(String token){
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
CookieUtil.addCookie(response,cookieDomain,"/","Authorization",token,cookieMaxAge,false);
}
}
package com.leon.oauth.service.impl;
import com.leon.oauth.service.LoginService;
import com.leon.oauth.util.AuthToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.Base64;
import java.util.Map;
/**
* 描述
*
* @author www.leon.com
* @version 1.0
* @package com.leon.oauth.service.impl *
* @since 1.0
*/
@Service
public class LoginServiceImpl implements LoginService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@Override
public AuthToken login(String username, String password, String clientId, String clientSecret, String grandType) {
//1.定义url (申请令牌的url)
//参数 : 微服务的名称spring.appplication指定的名称
ServiceInstance choose = loadBalancerClient.choose("user-auth");
String url =choose.getUri().toString()+"/oauth/token";
//2.定义头信息 (有client id 和client secr)
MultiValueMap<String,String> headers = new LinkedMultiValueMap<>();
headers.add("Authorization","Basic "+Base64.getEncoder().encodeToString(new String(clientId+":"+clientSecret).getBytes()));
//3. 定义请求体 有授权模式 用户的名称 和密码
MultiValueMap<String,String> formData = new LinkedMultiValueMap<>();
formData.add("grant_type",grandType);
formData.add("username",username);
formData.add("password",password);
//4.模拟浏览器 发送POST 请求 携带 头 和请求体 到认证服务器
/**
* 参数1 指定要发送的请求的url
* 参数2 指定要发送的请求的方法 PSOT
* 参数3 指定请求实体(包含头和请求体数据)
*/
HttpEntity<MultiValueMap> requestentity = new HttpEntity<MultiValueMap>(formData,headers);
ResponseEntity<Map> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestentity, Map.class);
//5.接收到返回的响应(就是:令牌的信息)
Map body = responseEntity.getBody();
//封装一次.
AuthToken authToken = new AuthToken();
//访问令牌(jwt)
String accessToken = (String) body.get("access_token");
//刷新令牌(jwt)
String refreshToken = (String) body.get("refresh_token");
//jti,作为用户的身份标识
String jwtToken= (String) body.get("jti");
authToken.setJti(jwtToken);
authToken.setAccessToken(accessToken);
authToken.setRefreshToken(refreshToken);
//6.返回
return authToken;
}
public static void main(String[] args) {
byte[] decode = Base64.getDecoder().decode(new String("Y2hhbmdnb3UxOmNoYW5nZ291Mg==").getBytes());
System.out.println(new String(decode));
}
}