我终于找到了问题所在.这次旅行比结果更令人满意,所以让我把它分解成我解决问题所采取的步骤.
总而言之,这不是Angular的问题.我发送的cookies 上有secureCookie
个标记.当我在没有https
的情况下测试应用程序时,angular应用程序似乎没有使用(或访问)200 OK
中接收到的Set-Cookie
报头.
我最初向服务器发送登录请求并处理其响应的代码是
return this.http.post(this.SIGNIN_USER_URL,body,httpOptions)
.map(response=>{
console.log('response from backend service',response);
let result= <ServerResponse>response;
console.log("result is "+result.result+' with additional information '+result.additionalInformation)
return result;
})
.catch(this.handleError);
我没有使用observe: 'response'
选项,这意味着响应将只包含正文,而不是标题.我将代码改为following,这样我就可以看到接收到了哪些头.
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
withCredentials: true,
observe: 'response' as 'response'
};
public signinUser(user:UserSigninInfo):any{
console.log('contacting server at '+this.API_URL +this.SIGNIN_USER_URL +" with user data "+user+ " with httpOptions "+httpOptions.withCredentials + ","+httpOptions.headers );
let signinInfo= new UserSignin(user);
let body = JSON.stringify(signinInfo);
return this.http.post(this.SIGNIN_USER_URL,body,httpOptions)
.catch(this.handleError);
}
上面的代码被调用如下.我更改它以获取响应中的标题
return this.bs.signinUser(user).subscribe((res:HttpResponse<any>)=>{console.log('response from server:',res);
console.log('response headers',res.headers.keys())
} );
我还创建了一个拦截器来打印传入和传出的消息(复制自SO)
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from "@angular/common/http";
import {Injectable} from "@angular/core";
import {Observable} from "rxjs/Observable";
import 'rxjs/add/operator/do';
@Injectable()
export class CustomInterceptor implements HttpInterceptor {
constructor() {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log("outgoing request",request);
request = request.clone({
withCredentials: true
});
console.log("new outgoing request",request);
return next
.handle(request)
.do((ev: HttpEvent<any>) => {
console.log("got an event",ev)
if (ev instanceof HttpResponse) {
console.log('event of type response', ev);
}
});
}
}
当我开始调试时,我注意到虽然服务器发送了10个标题,但只打印了9个
来自服务器的标题
在控制台上打印消息(缺少Set-Cookie
!我的应用程序需要获取身份验证cookie的标题)
0: "Content-Length"
1: "Content-Security-Policy"
2: "Content-Type"
3: "Date"
4: "Referrer-Policy"
5: "X-Content-Type-Options"
6: "X-Frame-Options"
7: "X-Permitted-Cross-Domain-Policies"
8: "X-XSS-Protection"
length: 9
这给了我一个方向,应用程序没有看到Set-Cookie
头.我原以为我可以通过在play framework exposedHeaders = ["Set-Cookie"]
中添加CORS
策略来解决这个问题,但这不起作用.后来我更仔细地看了看cookies ,注意到它的背景
Set-Cookie: id=...Secure; HTTPOnly
这让我觉得我的cookie设置可能不适合我的环境(localhost,没有HTTPS).我改变了Silhoutte的cookie设置
val config = CookieAuthenticatorSettings(secureCookie=false)
成功了!
虽然我会让上面的代码在secureCookie上工作,而且这不是Angular 的问题,但我希望有些人会发现这种方法很有帮助