0

我想在我的 http 标头中发送身份验证令牌以连接到我用 java 编写的后端 rest-api。

从角度来看,代码就像(service.ts):

    getDataFromBackend() {
      let headers = new Headers();
      headers.append('Content-Type', 'application/json');
      //this.getAuthToken() retrives auth token from cookies
      headers.append("authToken",this.getAuthToken());
      return this._http.get('url', {headers:headers})
                .map(this.parseData)
    }

    private parseData(res: Response) {
        return res.json || [];
    }

从后端:

@Path("/path")
@GET

public Response getData() {
  //retrive data from db and call required service to process
  return Response.ok(result)
                .header("Access-Control-Allow-Origin", "*")
                .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
                .status(Status.OK).build();
}

现在,当以角度调用服务方法时,出现错误。

请求标头详细信息:

Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.9
Access-Control-Request-Headers:authtoken,content-type
Access-Control-Request-Method:GET
Connection:keep-alive
Host:localhost:8085
Origin:http://localhost:3000
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36

回应是:

Authentication failed - Token absent

控制台错误:

OPTIONS http://localhost:8085/*url* 401 (Unauthorized)

Failed to load http://localhost:8085/*url*: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401.

我无法弄清楚如何解决这个问题?

4

2 回答 2

0

如果您将 JWT 与“不记名”身份验证一起使用:

getDataFromBackend() 
{
    return this._http.get('url', this.getAuthHeader(true)).map(this.parseData)
}

private parseData(res: Response) 
{
    return res.json || [];
}

private getAuthHeader(includeJsonContentType?: boolean): RequestOptions
{
  let headers = new Headers({
    'Authorization': 'Bearer ' + this.getAuthToken() });

  if (includeJsonContentType)
    headers.append("Content-Type", "application/json");

  headers.append("Accept", "application/vnd.iman.v01+json, application/json, text/plain, */*");
  headers.append("App-Version", "01");

  return new RequestOptions({ headers: headers });
}
于 2018-02-02T07:51:04.683 回答
0

继续我的评论,这似乎是一个 CORS 问题。

您可以通过使用过滤器并将适当的标头附加到您的响应中来解决此问题,如下所示:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)

public class CustomCorsFilter implements Filter {

@Resource
    private Environment environment;    

    @Override
    public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
            throws IOException, ServletException {
        final HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin",
                environment.getProperty("cors.request.allowed-origin"));
        response.setHeader("Access-Control-Allow-Methods",
                environment.getProperty("cors.request.allowed-methods"));
        response.setHeader("Access-Control-Allow-Headers",
                environment.getProperty("cors.request.allowed-headers"));
        response.setHeader("Access-Control-Max-Age", environment.getProperty("cors.request.max-age"));
        if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);    
        }
    }

    @Override
    public void destroy() {
        // TODO destroy logic (if any) to be here.
    }

    @Override
    public void init(final FilterConfig config) throws ServletException {
        // TODO init logic (if any) to be here.
    }
}

我假设您在 application.properties 中保留这些标头的值,如下所示:

cors.request.allowed-origin=*
cors.request.allowed-methods=POST, PUT, GET, OPTIONS, DELETE, PATCH
cors.request.allowed-headers=Authorization, Content-Type
cors.request.max-age=3600

否则,您可以直接将这些值放入您的代码中,而不是从环境中获取它们。

密切关注 cors.request.allowed-headers。您需要将标题名称完全指定为您将从客户端使用的标题名称。您可以将其设置为 Authorization / myAuthToken 或任何其他名称,但标准是使用Authorization

于 2018-02-02T08:56:43.110 回答