问题
I do not manage to get my application running. I was reading about this the whole day, tried a bunch of stuff, but in the end nothing did work. In the last attempt I tried this link. I have the java back end as a RESTful web service without any additional framework like Jersey or RESTeasy, just pure java. There I have my login POST method:
@POST
@Path("login")
@Produces(value = "application/json")
public Response login() {
AccountAuthentificator authentificator = AccountAuthentificator.getInstance();
Status status = Response.Status.OK;
String credentialValue = getHeaderValue(AccountAuthentificator.AUTH_CREDENTIALS);
if (credentialValue == null) {
status = Response.Status.FORBIDDEN;
return WebServiceUtil.createResponse(status, "Missing account credentials in header.");
}
try {
LoginResponse res = authentificator.login(credentialValue);
return WebServiceUtil.createResponse(status, res);
} catch (AccessControlException e) {
status = Response.Status.FORBIDDEN;
return WebServiceUtil.createResponse(status,
"User does not exist. Please verify your user name and password.");
}
}
The WebServiceUtil.createResponse method basically adds the necessary headers as you can see here:
public static Response createResponse(Status status, Object responseContent) {
ResponseBuilder resBuilder = Response.status(status.getStatusCode());
resBuilder.header("Access-Control-Allow-Origin", "*");
resBuilder.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
resBuilder.header("Access-Control-Allow-Credentials", "true");
resBuilder.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
resBuilder.allow("OPTIONS");
resBuilder.entity(getJSONAsString(responseContent));
return resBuilder.build();
}
I also saw people used another approach. It was with filters, like this example. I was also wondering if my implementation differs from this and where exactly is the preflight defined - in my implementation it is the .allow("OPTIONS") which does that, but you can correct me of I am wrong.
And then I have my web application where I call this POST method. I am using AngularJS for this. In my AuthenticateController controller I have the Login method, which is called on submit in the login form. The implementation looks like this:
function Login(username, password) {
// CreateLoginHeader creates the authorization token through the login values username and password
var authdata = CreateLoginHeader(username, password);
var config = {
withCredentials: true,
headers: { 'Authorization': authdata }
};
$http.post('http://XXXX', config).then(SuccessLogin, ErrorLogin);
}
Does anybody know what is wrong here? Through the chrome developer tools I can see I get the error "XMLHttpRequest cannot load 'placeholder-server-URL'. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'placeholder-client-URL' is therefore not allowed access.".
Should I be adding those two header values on the client side, when calling my back end:
- Access-Control-Request-Method
- Access-Control-Request-Headers
回答1:
The Options request is not handled by login
, so createResponse
is not called.
Have a look at: https://blogs.oracle.com/theaquarium/entry/supporting_cors_in_jax_rs (you should implement a javax.ws.rs.container.ContainerResponseFilter
, see How to handle CORS using JAX-RS with Jersey)
Another possibility for your code here (but not if you develop a 'real' application): add @javax.ws.rs.OPTIONS
to your method like you did with @javax.ws.rs.POST
.
来源:https://stackoverflow.com/questions/35808288/failed-http-post-request-because-of-cors