Angular7向.NET Owin发送含&的密码时Web API Token认证异常
问题根源与解决方案
你遇到的核心问题是URL编码处理不当:&是application/x-www-form-urlencoded格式的参数分隔符,你直接将包含&的密码拼接到请求体字符串中,后端会把&后面的内容识别为新的请求参数,导致密码被截断。
推荐解决方案:使用Angular的HttpParams构建请求体
这是Angular官方推荐的方式,它会自动帮你完成参数的URL编码,避免手动拼接的错误。修改你的登录代码如下:
public login(username: string, password: string): Observable<UserLoginClaims> { // 用HttpParams构建参数,自动处理URL编码 const tokenParams = new HttpParams() .set('username', username) .set('password', password) .set('grant_type', 'password'); const tokenHeaders: HttpHeaders = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded', 'No-Auth': 'True' }); return this.httpClient.post<UserPzToken>('http://localhost:10392/token', tokenParams.toString(), { headers: tokenHeaders }).pipe( concatMap((userPzToken: UserPzToken) => { if (this.localStorageService.setItem('UserPzToken', userPzToken)) { this.UserLogged = true; } return this.apiService.getItem<UserLoginClaims>('http://localhost:10392/Auth/GetUserClaims').pipe( tap((userLoginClaims: UserLoginClaims) => this.localStorageService.setItem('UserLoginClaims', userLoginClaims)) ); }), catchError(this.errorHandleService.handleError) ); }
备选方案:手动URL编码参数值
如果你坚持手动拼接请求体字符串,可以使用JavaScript的encodeURIComponent()函数对每个参数值单独编码:
public login(username: string, password: string): Observable<UserLoginClaims> { // 对用户名、密码分别做URL编码 const tokenData = `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&grant_type=password`; const tokenHeaders: HttpHeaders = new HttpHeaders({ 'Content-Type': 'application/x-www-urlencoded', 'No-Auth': 'True' }); // 后续逻辑保持不变 }
后端无需修改
你的.NET Owin后端代码是正常的,OAuth中间件会自动解码URL编码后的参数值,只要前端正确传递编码后的请求体,OAuthGrantResourceOwnerCredentialsContext.Password就能拿到完整的密码(比如123&123abc)。
内容的提问来源于stack exchange,提问作者Vladimir Potapov
相关产品推荐
相关产品推荐

