我有一个用Java编写的REST登录操作(用于服务器端)。 JWT也被使用。
客户端正在使用Angular 5下的HTTP客户端来访问/执行REST API。
正在发生的是登录REST功能(使用HTTP客户端)被执行。之后,返回信息并返回代码状态为200(意味着一切正常)。
根据Chrome浏览器"网络"选项卡,RC返回200。
即使是这种情况,"赶上"语句(与REST登录调用相关联)始终执行。
下面列出了代码。
我做错了什么?
TIA
来自浏览器的信息
控制台日志
admin-services.service.ts:208 TypeError: Cannot read property 'json' of null
at MapSubscriber.eval [as project] (admin-services.service.ts:176)
at MapSubscriber._next (map.js:79)
at MapSubscriber.Subscriber.next (Subscriber.js:91)
at MapSubscriber._next (map.js:85)
at MapSubscriber.Subscriber.next (Subscriber.js:91)
at FilterSubscriber._next (filter.js:90)
at FilterSubscriber.Subscriber.next (Subscriber.js:91)
at MergeMapSubscriber.notifyNext (mergeMap.js:151)
at InnerSubscriber._next (InnerSubscriber.js:25)
at InnerSubscriber.Subscriber.next (Subscriber.js:91)
(anonymous) @ admin-services.service.ts:208
CatchSubscriber.error @ catchError.js:105
MapSubscriber._next @ map.js:82
Subscriber.next @ Subscriber.js:91
MapSubscriber._next @ map.js:85
Subscriber.next @ Subscriber.js:91
FilterSubscriber._next @ filter.js:90
Subscriber.next @ Subscriber.js:91
MergeMapSubscriber.notifyNext @ mergeMap.js:151
InnerSubscriber._next @ InnerSubscriber.js:25
Subscriber.next @ Subscriber.js:91
onLoad @ http.js:2270
ZoneDelegate.invokeTask @ zone.js:425
onInvokeTask @ core.js:4744
ZoneDelegate.invokeTask @ zone.js:424
Zone.runTask @ zone.js:192
ZoneTask.invokeTask @ zone.js:499
invokeTask @ zone.js:1540
globalZoneAwareCallback @ zone.js:1566
XMLHttpRequest.send (async)
scheduleTask @ zone.js:2933
ZoneDelegate.scheduleTask @ zone.js:411
onScheduleTask @ zone.js:301
ZoneDelegate.scheduleTask @ zone.js:405
Zone.scheduleTask @ zone.js:236
Zone.scheduleMacroTask @ zone.js:259
(anonymous) @ zone.js:2966
proto.(anonymous function) @ zone.js:1366
(anonymous) @ http.js:2366
Observable._trySubscribe @ Observable.js:172
Observable.subscribe @ Observable.js:160
subscribeToResult @ subscribeToResult.js:23
MergeMapSubscriber._innerSub @ mergeMap.js:138
MergeMapSubscriber._tryNext @ mergeMap.js:135
MergeMapSubscriber._next @ mergeMap.js:118
Subscriber.next @ Subscriber.js:91
ScalarObservable._subscribe @ ScalarObservable.js:51
Observable._trySubscribe @ Observable.js:172
Observable.subscribe @ Observable.js:160
MergeMapOperator.call @ mergeMap.js:92
Observable.subscribe @ Observable.js:157
FilterOperator.call @ filter.js:61
Observable.subscribe @ Observable.js:157
MapOperator.call @ map.js:57
Observable.subscribe @ Observable.js:157
MapOperator.call @ map.js:57
Observable.subscribe @ Observable.js:157
CatchOperator.call @ catchError.js:80
Observable.subscribe @ Observable.js:157
AdminLoginComponent.onSubmit @ admin-login.component.ts:80
(anonymous) @ AdminLoginComponent.html:19
handleEvent @ core.js:13581
callWithDebugContext @ core.js:15090
debugHandleEvent @ core.js:14677
dispatchEvent @ core.js:9990
(anonymous) @ core.js:12332
schedulerFn @ core.js:4351
SafeSubscriber.__tryOrUnsub @ Subscriber.js:239
SafeSubscriber.next @ Subscriber.js:186
Subscriber._next @ Subscriber.js:127
Subscriber.next @ Subscriber.js:91
Subject.next @ Subject.js:56
EventEmitter.emit @ core.js:4319
NgForm.onSubmit @ forms.js:5751
(anonymous) @ AdminLoginComponent.html:19
handleEvent @ core.js:13581
callWithDebugContext @ core.js:15090
debugHandleEvent @ core.js:14677
dispatchEvent @ core.js:9990
(anonymous) @ core.js:10611
(anonymous) @ platform-browser.js:2628
ZoneDelegate.invokeTask @ zone.js:425
onInvokeTask @ core.js:4744
ZoneDelegate.invokeTask @ zone.js:424
Zone.runTask @ zone.js:192
ZoneTask.invokeTask @ zone.js:499
invokeTask @ zone.js:1540
globalZoneAwareCallback @ zone.js:1566
core.js:1427 ERROR Error: Unexpected Error Code: undefined
at CatchSubscriber.eval [as selector] (admin-services.service.ts:216)
at CatchSubscriber.error (catchError.js:105)
at MapSubscriber._next (map.js:82)
at MapSubscriber.Subscriber.next (Subscriber.js:91)
at MapSubscriber._next (map.js:85)
at MapSubscriber.Subscriber.next (Subscriber.js:91)
at FilterSubscriber._next (filter.js:90)
at FilterSubscriber.Subscriber.next (Subscriber.js:91)
at MergeMapSubscriber.notifyNext (mergeMap.js:151)
at InnerSubscriber._next (InnerSubscriber.js:25)
管理-services.service.ts
[... snip ...]
adminLogin(username, password): Observable<boolean> {
let url = `${this._apiRoot}/login`;
let tokenResp = {};
return this.http.post(url, JSON.stringify({ username: username, password: password }))
.map((response: Response) => {
// login successful if there's a token in the response
let token = response.json() && response.json().token;
if (token) {
let t = JWT(token);
console.log("-- what is in the token --");
console.log(t);
//initiialize
let setUser: User = ANONYMOUS_USER;
// need to set the value here
this.userLoggedIn.next(setUser);
// store username and jwt token in local storage to keep user logged in between page refreshes
// => SET BACK: localStorage.setItem('currentUser', JSON.stringify(this.userLoggedIn));
// => SET BACK: this.userLoggedIn = JSON.parse(localStorage.getItem('currentUser'));
// return true to indicate successful login
return true;
} else {
// throw an error that the token was "whack"
return Observable.throw(
new Error("APX: the token was not set properly"));
}
//return response.json();
})
.catch(e => {
console.error(e);
if (e.status === 401) {
return Observable.throw(
new Error("Error Code : 401 - Unauthorized Access To Server "));
}
return Observable.throw(
new Error( "Unexpected Error Code: " + e.status ));
});
}
[... snip ...]
更新 没有回应。
登录正在使用JWT。该信息作为标题的一部分返回。
Authorization:Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXJyZW5jZWRhcmJ5IiwiaWQiOjQ4LCJ0ZW5hbnRpZCI6MjU2LCJrZXlpZCI6MCwidXNlcm5hbWUiOiJ0ZXJyZW5jZWRhcmJ5IiwiZW1haWxhZGRyIjoidGVycmVuY2VAZGFyYnkuY29tIiwicm9sZSI6MSwiZmlyc3RuYW1lIjoidGVycmVuY2UgIiwibGFzdG5hbWUiOiJkYXJieSIsImV4cCI6MTUxODUwNTcwMX0.FNlvx-3WePXWEoqkDLfMw3GkkNcy_S-V3TcikBTfzOo
更新
代码
return this.http.post(url, JSON.stringify({ username: username, password: password }))
.map((response: Response) => {
console.log( "==> looking for the answer - begin ");
console.log( response );
console.log( "==> looking for the answer - end ");
生成的值
NgForm {submitted: true, _directives: Array(2), ngSubmit: EventEmitter, form: FormGroup}control: (...)controls: (...)dirty: (...)disabled: (...)enabled: (...)errors: (...)form: FormGroup {validator: null, asyncValidator: null, _onCollectionChange: ƒ, pristine: false, touched: true, …}formDirective: (...)invalid: (...)ngSubmit: EventEmitter {_isScalar: false, observers: Array(1), closed: false, isStopped: false, hasError: false, …}path: (...)pending: (...)pristine: (...)status: (...)statusChanges: (...)submitted: truetouched: (...)untouched: (...)valid: (...)value: (...)valueChanges: (...)_directives: (2) [NgModel, NgModel]__proto__: ControlContainer
admin-login.component.ts:72 getting ready to go call the service
admin-login.component.ts:76 values for id and password terrencedarby ----- 3333333333
admin-services.service.ts:175 ==> looking for the answer - begin
admin-services.service.ts:176 null
admin-services.service.ts:177 ==> looking for the answer - end
答案 0 :(得分:1)
问题在于以下代码
// login successful if there's a token in the response
let token = response.json() && response.json().token;
if (token) {
...
}
新的angular 5 httpClient默认返回JSON对象,因为响应对象上的.json()调用是多余的。如果您在尝试将其解析为json之前添加响应本身的console.log,则可以确切地看到返回的对象。
更新: 由于标题包含令牌,您可以像这样提取它,
let token = res.headers.get("Authorization");
答案 1 :(得分:1)
由于您使用的是Angular 5,因此您应该考虑使用HttpClient而不是旧的已弃用的http。
要获得标题,您需要两件事
所以你的服务器响应应该有那个标题
Access-Control-Expose-Headers: Authorization
(见https://stackoverflow.com/a/48306230/1160794)
这是修改后的代码
adminLogin(username, password): Observable<boolean> {
let url = `${this._apiRoot}/login`;
let tokenResp = {};
//to post json with HttpClient
const headers = new HttpHeaders({'Content-Type':'application/json; charset=utf-8'})
return this.http.post(url, JSON.stringify({ username: username, password: password }), headers)
.map((response: HttpResponse) => {
// login successful if there's a token in the response
let token = response.header.get('Authorization');
if (token) {
let t = JWT(token);
console.log("-- what is in the token --");
console.log(t);
//initiialize
let setUser: User = ANONYMOUS_USER;
// need to set the value here
this.userLoggedIn.next(setUser);
// store username and jwt token in local storage to keep user logged in between page refreshes
// => SET BACK: localStorage.setItem('currentUser', JSON.stringify(this.userLoggedIn));
// => SET BACK: this.userLoggedIn = JSON.parse(localStorage.getItem('currentUser'));
// return true to indicate successful login
return true;
} else {
// throw an error that the token was "whack"
return Observable.throw(
new Error("APX: the token was not set properly"));
}
//return response.json();
})
.catch(e => {
console.error(e);
if (e.status === 401) {
return Observable.throw(
new Error("Error Code : 401 - Unauthorized Access To Server "));
}
return Observable.throw(
new Error( "Unexpected Error Code: " + e.status ));
});
}