我正在使用Spotify Web API使用angular创建Web应用。
虽然我能够对用户进行身份验证并获得播放列表/曲目,甚至创建播放列表等。但是,我仍然坚持在用户同意我的应用范围后如何从redirect_url获取access_token。
目前,我可以使用以下代码来完成上述操作……但这是一种非常糟糕且效率低下的方法。
Service.ts:
// ASK USER TO GRANT PERMISSION FOR THE FOLLOWING SCOPES
Login(showDialog = true) {
const state = uuid();
localStorage.setItem('xsrf-token', state);
const params = {
response_type: 'token',
client_id: "ec540590bb6449a181edhjdjsdjkdshasbdjk",
redirect_uri: "http://localhost:4200/selectionMenu",
scope:
'user-top-read%20user-read-private%20playlist-read-private%20user-library-modify%20playlist-modify-public%20user-follow-read%20user-read-playback-state%20user-modify-playback-state%20user-read-recently-played%20user-read-currently-playing%20user-follow-modify%20playlist-modify-private%20playlist-read-collaborative%20user-library-read%20user-read-email',
state,
show_dialog: `${showDialog}`
}
const redirectUrl = `https://accounts.spotify.com/authorize?${qs.stringify(params)}`;
window.location.href = redirectUrl;
}
此后,我将显示以下屏幕:
用户活动后(如果他单击“同意”),spotify服务将重定向到以下网址:
http://localhost:4200/selectionMenu
但会将access_token附加到上述网址之后,因此我的页面将重定向到的最终网址如下:
http://localhost:4200/selectionMenu#access_token=BQASUoH7jashdjakshdashvday63hvsjadjhqBEWmVi9bKNg7EBF7Dt2dCvSNWLlQ3zUOp6hGuLfvJ9QH4PXRLTz4AajPDyBW7SV9lXhFb_IF25qb7hheUsvyg7pX-zD-TsOtbRCb7ohF86wrjWGFRXuugT-mnWESBMCRVSxTi34nOcG4VpvM-Ew9F0kl1vq5zdsSRSnCvZwmsQNGngDVpj2rsS2nQG0EIXdqTmSut0CdZFFobz5k9ojpbw971ye5dl1cXnHlc&token_type=Bearer&expires_in=3600&state=59418612-e4cb-46bb-90af-d01f7a2c790a
屏幕如下:
要从上述网址中提取access_token,我目前正在执行以下操作:
在Component.ts中:
currentWindowUrl() {
const pathname = new URL(window.location.href).pathname;
const redirectURL = window.location.href.split('#');
usableURL = redirectURL[1].split('&');
this.getTokens();
}
getTokens() {
const accessToken = usableURL[0].split('=')[1];
const tokenType = usableURL[1].split('=')[1];
const refreshTime = usableURL[2].split('=')[1];
const state = usableURL[3].split('=')[1];
// pass accessToken to service and store it.
this.spotifyAuthorizeService.saveAccessToken(accessToken);
}
我基本上是使用window.location.href并将其拆分,直到获得access_token为止,这听起来很sound脚。
我的问题
->如何通过Spotify将访问令牌附加到redirect_url,以一种更好的方式并将其存储在localStorage中[不适用于xhr攻击],还有其他更好的存储方式,以便可以在我的应用中将其用于其他所有页面,并每隔60分钟(令牌过期时间)刷新一次。
->有没有办法不显示URL中#之后的部分,即access_token,这样我就不会放弃它。
Angular-Auth-OIDC
我已遵循文档并提出了以下配置:
assets / auth.clientConfiguration.json:
{
"stsServer": "https://accounts.spotify.com/authorize",
"redirect_url": "http://localhost:4200/selectionMenu",
"client_id": "ec5405hgasfdhasfdashdgdcbd27987aef6",
"response_type": "token",
"scope": "user-top-read%20user-read-private%20playlist-read-private%20user-library-modify%20playlist-modify-public%20user-follow-read%20user-read-playback-state%20user-modify-playback-state%20user-read-recently-played%20user-read-currently-playing%20user-follow-modify%20playlist-modify-private%20playlist-read-collaborative%20user-library-read%20user-read-email",
"post_logout_redirect_uri": "https://localhost:4200/",
"start_checksession": true,
"silent_renew": true,
"silent_renew_url": "https://accounts.spotify.com/authorize",
"post_login_route": "/selectionMenu",
"forbidden_route": "/forbidden",
"unauthorized_route": "/unauthorized",
"log_console_warning_active": true,
"log_console_debug_active": true,
"max_id_token_iat_offset_allowed_in_seconds": 10
}
然后出现以下错误,我将为应用提供服务:
当我单击登录时,应用程序重定向到以下URL:
https://accounts.spotify.com/authorize/.well-known/openid-configuration
最后出现405错误。
我的理解
我知道该URL配置错误,我不确定在stsServer中指定哪个URL,我猜它是spotify的URL,因为它提供了令牌服务,但是我不确定在json文件中配置的URL是否正确。
对此有任何见识会有所帮助。
谢谢!
答案 0 :(得分:1)
您可以使用OIDC客户端从您自己的身份服务器提供身份验证令牌。 我建议使用两个角度库:
NG OIDC客户端-https://github.com/sourcenetwork/ng-oidc-client
Angular Auth OIDC客户端-https://github.com/damienbod/angular-auth-oidc-client
您可以根据自己的问题实现以下目标:
您现在不必使用Spotify服务进行手动操作。
让我知道是否有帮助。
答案 1 :(得分:1)
直接与第三方身份验证提供程序对您的客户端进行身份验证始终是个坏主意。
相反,您应该设置一个后端来保存此身份验证,您的客户端将不会保存第三方身份验证提供程序的访问令牌,而将保存您的后端。
您可以使用URLSearchParams来完成您需要使用URL参数播放的完美工作。
getTokens() {
var urlParams = new URLSearchParams(window.location.search);
return {access_token: urlParams.get("access_token"), refresh_token: urlParams.get("refresh_token")}
}
Angular提供了一种使用ActivatedRoute动态播放URL的方法。
constructor(private route: ActivatedRoute) {
this.route.paramMap.pipe(params => {
this.yourservice.saveToken(params.get("access_token"), params.get("refresh_token"))
})
}
这些是示例,可能与您的代码或上下文不匹配。
以下是可以用来实现目标的库的列表: