Javascript OAuth2和angular-auth2-oidc库-PKCE代码流的问题
我是OAuth2和库的新手,所以如果我犯了一些新手错误,请容忍我 我想要实现的目标:用户将单击主页中的登录链接,他将被发送到提供商的站点进行登录,然后使用令牌重定向回主页 到目前为止的结果:一个用户被发送到提供商的站点登录并成功发送回我的站点主页,但我没有得到任何令牌。 我在控制台的Javascript OAuth2和angular-auth2-oidc库-PKCE代码流的问题,javascript,angular,oauth-2.0,angular-oauth2-oidc,Javascript,Angular,Oauth 2.0,Angular Oauth2 Oidc,我是OAuth2和库的新手,所以如果我犯了一些新手错误,请容忍我 我想要实现的目标:用户将单击主页中的登录链接,他将被发送到提供商的站点进行登录,然后使用令牌重定向回主页 到目前为止的结果:一个用户被发送到提供商的站点登录并成功发送回我的站点主页,但我没有得到任何令牌。 我在控制台的ngOnit()中输出了一些数据,它们都是null、未定义或false 在ngOnit()函数中,我还输出了一些事件,在de控制台中得到的事件是token\u refresh\u error。我没有在我的代码中明确地
ngOnit()
中输出了一些数据,它们都是null、未定义或false
在ngOnit()
函数中,我还输出了一些事件,在de控制台中得到的事件是token\u refresh\u error
。我没有在我的代码中明确地进行任何令牌刷新,但仍然会出现此错误
在这篇文章的错误子标题下,我添加了关于错误的屏幕截图
以下是我的配置和实现:
authorization_endpoint "https://DOMAIN_PROVIDER/op/v1/auth"
code_challenge_methods_supported
0 "plain"
1 "S256"
end_session_endpoint "https://DOMAIN_PROVIDER/op/v1/logout"
grant_types_supported
0 "authorization_code"
id_token_signing_alg_values_supported
0 "RS256"
issuer "https://DOMAIN_PROVIDER/op"
jwks_uri "https://DOMAIN_PROVIDER/op/v1/keys"
response_modes_supported
0 "query"
1 "fragment"
2 "form_post"
response_types_supported
0 "code"
scopes_supported
0 "openid"
subject_types_supported
0 "public"
token_endpoint "https://DOMAIN_PROVIDER/op/v1/token"
token_endpoint_auth_methods_supported
0 "client_secret_basic"
1 "client_secret_post"
userinfo_endpoint "https://DOMAIN_PROVIDER/op/v1/userinfo"
以下是my OAuth2提供程序的openid配置:
authorization_endpoint "https://DOMAIN_PROVIDER/op/v1/auth"
code_challenge_methods_supported
0 "plain"
1 "S256"
end_session_endpoint "https://DOMAIN_PROVIDER/op/v1/logout"
grant_types_supported
0 "authorization_code"
id_token_signing_alg_values_supported
0 "RS256"
issuer "https://DOMAIN_PROVIDER/op"
jwks_uri "https://DOMAIN_PROVIDER/op/v1/keys"
response_modes_supported
0 "query"
1 "fragment"
2 "form_post"
response_types_supported
0 "code"
scopes_supported
0 "openid"
subject_types_supported
0 "public"
token_endpoint "https://DOMAIN_PROVIDER/op/v1/token"
token_endpoint_auth_methods_supported
0 "client_secret_basic"
1 "client_secret_post"
userinfo_endpoint "https://DOMAIN_PROVIDER/op/v1/userinfo"
这是我的实现:
authorization_endpoint "https://DOMAIN_PROVIDER/op/v1/auth"
code_challenge_methods_supported
0 "plain"
1 "S256"
end_session_endpoint "https://DOMAIN_PROVIDER/op/v1/logout"
grant_types_supported
0 "authorization_code"
id_token_signing_alg_values_supported
0 "RS256"
issuer "https://DOMAIN_PROVIDER/op"
jwks_uri "https://DOMAIN_PROVIDER/op/v1/keys"
response_modes_supported
0 "query"
1 "fragment"
2 "form_post"
response_types_supported
0 "code"
scopes_supported
0 "openid"
subject_types_supported
0 "public"
token_endpoint "https://DOMAIN_PROVIDER/op/v1/token"
token_endpoint_auth_methods_supported
0 "client_secret_basic"
1 "client_secret_post"
userinfo_endpoint "https://DOMAIN_PROVIDER/op/v1/userinfo"
//主页组件
export class HomeComponent implements OnInit {
private oAuthConfig: AuthConfig;
constructor(private oAuthService: OAuthService) { }
ngOnInit() {
// IN THIS METHOD I'M OUTPUTTING ALOT OF STUFF TO THE CONSOLE TO SEE IF IT IS WORKING
if (!this.oAuthService.getAccessToken()) {
this.initOAuthConfig();
console.log('__________ACCESS-TOKEN IS NOT SET___________');
} else {
console.log('___ACCESS-TOKEN IS SET:', this.oAuthService.getAccessToken());
}
console.log('_____GRANTED-SCOPE:', this.oAuthService.getGrantedScopes());
console.log('______IDENTITY-CLAIMS:', this.oAuthService.getIdentityClaims());
console.log('______HAS-ACCESS-TOKEN?:', this.oAuthService.hasValidAccessToken());
console.log('_____HAS-ACCESS-TOKEN?:', this.oAuthService.hasValidIdToken());
// HERE I'M OUTPUTTNG THE EVENTS TO SEE WHAT IS GOING ON
this.oAuthService.events.subscribe((e: OAuthErrorEvent) => {
if (e.type === 'token_received') {
this.logger.log('____________TOKEN RECEIVED');
}
this.logger.log('______====================EVENT-TYPE:', e.type);
this.logger.log('______====================EVENT-REASON:', e.reason);
this.logger.log('______====================EVENT-PARAMS:', e.params);
});
if (this.oAuthService.hasValidAccessToken()) {
this.oAuthService.loadUserProfile().then((t) => {
console.log('----USER-PROFILE:', t);
});
} else {
this.logger.log('----HAS VALID ACCESS TOKEN');
}
}
private initOAuthConfig(): void {
this.oAuthConfig = {
redirectUri: window.location.origin + '/login/oauth2/myapp',
postLogoutRedirectUri: window.location.origin + '/logout',
clientId: 'CLIENT-ID',
scope: 'openid, rrn, profile',
oidc: true,
issuer: 'https://DOMAIN_PROVIDER/op',
responseType: 'code',
showDebugInformation: true,
tokenEndpoint: 'DOMAIN_PROVIDER/op/v1/token',
jwks: {'keys': ['DOMAIN_PROVIDER/op/v1/keys']}
};
this.oAuthService.setStorage(sessionStorage);
this.oAuthService.configure(this.oAuthConfig);
this.oAuthService.loadDiscoveryDocumentAndTryLogin();
}
//包含登录函数的类
export class HeaderComponent {
constructor(private oAuthService: OAuthService) { }
public login() {
this.oAuthService.initCodeFlow();
}
public logout() {
this.oAuthService.logOut();
}
}
// The html of the header component which contains the login link
<a (click)="login()" title="Login">
Login
</a>
导出类标题组件{
构造函数(专用oAuthService:oAuthService){}
公共登录(){
this.oAuthService.initCodeFlow();
}
公共注销(){
this.oAuthService.logOut();
}
}
//包含登录链接的标题组件的html
2)在下面的屏幕截图中,您将看到事件类型之一是token\u refresh\u error
。而事件原因是错误请求
。它正试图向https//DOMAIN\u PROVIDER/op/v1/token
发出请求,但在deinitOAuthConfig()方法中失败,因为我添加了tokenEndPoint
属性。
您还可以看到错误是错误:“无效的授权”
。
屏幕截图的第二行显示获取令牌时出错
export class HeaderComponent {
constructor(private oAuthService: OAuthService) { }
public login() {
this.oAuthService.initCodeFlow();
}
public logout() {
this.oAuthService.logOut();
}
}
// The html of the header component which contains the login link
<a (click)="login()" title="Login">
Login
</a>
我添加了jwks:{'keys':['https://DOMAIN_PROVIDER/op/v1/keys']}
toinitOAuthConfig()认为它可以解决问题,但它没有
//控制台的应用程序选项卡:会话存储
从控制台的“应用程序”选项卡中,我可以看到会话存储中有一些数据的键值对(本地存储中没有数据)。请参见下一个屏幕截图:
我的目标是分两个阶段实施您的解决方案:
- 首先了解OAuth和OpenIDConnect设计模式——我希望通过一个简单的TypeScript代码示例,我能在这方面提供帮助
- 考虑将示例转换为角度的最佳方法,我相信您可以很容易地做到这一点
配置文件
我喜欢通过JSON配置来表示OAuth设置-请参阅。您可以更新文件以匹配您的配置,运行我的示例,然后希望您能看到一个令牌返回
API客户责任
当UI调用API时,它必须首先获得访问令牌,并且UI还必须处理过期的/401响应-请参阅
OAUTH客户责任
API客户端调用以获取令牌,该令牌使用OIDC客户端库来管理重定向、响应和返回令牌
解释性博客帖子
另请参阅这些文章,我的目的是保持视觉效果和易于阅读: