密碼模式
前端 -> 令牌
Postman 模擬前端進行 Post 請求令牌
在 Postman 中模擬一個 Post 請求:
http://localhost:7001/service-uaa/oauth/token?client_id=c1&client_secret=123&grant_type=password&username=zhangsan&password=123
在 Postman 中模擬 Post 請求時谆趾,參數(shù)的傳遞方式有很多選擇沪蓬,可以是 Params来候,也可以是 Body 的 form-data 和 x-www-form-urlencoded营搅,但無法通過 ray 傳遞 JSON 形式的數(shù)據(jù)。
前端 -> 后端 -> RestTemplate -> 令牌
錯誤1
java.lang.IllegalStateException: No instances available for localhost
at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute(RibbonLoadBalancerClient.java:119) ~[spring-cloud-netflix-ribbon-2.1.3.RELEASE.jar:2.1.3.RELEASE]
......
這個錯誤的原因是园欣,RestTemplate 開啟了 Ribbon 的負載均衡休蟹,因此其請求的 url 只能是 服務名,不再是具體地址绑榴。
錯誤2
Could not extract response: no suitable HttpMessageConverter found for response type [class com.alibaba.fastjson.JSONObject] and content type [text/html;charset=utf-8]
這是因為通過 Resttemplate 請求令牌時發(fā)生異常拣展,異常的返回結果并不是 json 結構彭沼,無法轉成JSONObject。
查看 log 發(fā)現(xiàn)姓惑,url 中的服務名確實替換成了對應的 ip 和端口按脚,但缺少了上下文路徑辅搬,因為在 yml 中設置了 server.servlet.context-path堪遂,而 url 中沒有指定溶褪,導致請求 404,返回了一個 text/html 的結果吹菱。
錯誤3
Request URI does not contain a valid hostname: http://aaa_bbb/service/uaa/oauth/token
這是因為 url 中的服務名不能帶下劃線。
登錄代碼
@Value("${client.client-id}")
private String clientId;
@Value("${client.client-secret}")
private String clientSecret;
@Value("${spring.application.name}")
private String msName;
@Autowired
private RestTemplate restTemplate;
/**
* 登錄并返回訪問令牌
*
* @param username 用戶名
* @param password 密碼
* @return 訪問令牌
*/
@PostMapping("/login")
public JSONObject login(String username, String password) {
// 請求地址
String url = "http://" + msName + contextPath + "/oauth/token";
// 請求請求參數(shù)
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("client_id", clientId);
body.add("client_secret", clientSecret);
body.add("grant_type", "password");
body.add("username", username);
body.add("password", password);
// 設置頭部信息
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(body, headers);
return restTemplate.postForObject(url, httpEntity, JSONObject.class);
}