请求令牌

密码模式

前端 -> 令牌

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 请求时,参数的传递方式有很多选择,可以是 Params,也可以是 Body 的 form-data 和 x-www-form-urlencoded,但无法通过 ray 传递 JSON 形式的数据。

前端 -> 后端 -> 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 请求令牌时发生异常,异常的返回结果并不是 json 结构,无法转成JSONObject。
查看 log 发现,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";

    // 请求请求参数
    MultiValueMap 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> httpEntity = new HttpEntity<>(body, headers);
    return restTemplate.postForObject(url, httpEntity, JSONObject.class);
}

你可能感兴趣的:(请求令牌)