繁体   English   中英

python 如何从 URL 中提取 hash 片段?

[英]How can python extract a hash fragment from a URL?

我正在使用 Spotify 的 API 构建 python flask 应用程序。 Spotify 的 API 的用户认证部分将 app id(client_id)、scope 等连接到最后 Spotify base url: Z5E056C500A1C4B6A7110B50D807 /s.accounts.com (接下来将类似于 client_id=94857&scope=read)。 URL 将用户重定向到身份验证页面,在那里他们可以批准我的应用访问他们的 Spotify 数据(这意味着现在 API 应该能够发送请求)。 After they approve, they are taken to redirect URL (which the owner of the Spotify API user (me) inputs into the app's settings) and following the redirect URL is a variable called "access_token" which is a "hash fragment". 我需要这个 access_token 才能调用 API,因为它是用户自定义的必需参数,但我无法访问它,因为它前面有一个“#”。 url 看起来像这样:

https://myRedirectURL.com/callback#access_token=NwAExz...BV3O2Tk&token_type=Bearer&expires_in=3600&state=123

我可以从我的 python 函数访问这个 url 的所有部分,除了包含和后面的“#”字符的信息,这是我需要的信息,因为它没有访问权限。 我在另一个 Stackoverflow 帖子上读到后端无法访问 hash 片段。

我可以让用户手动复制整个 URL 或只是访问令牌并将其输入到我的应用程序中,以便它拥有数据,但我想避免这种情况并通过让应用程序提取它而不是为用户自动化该过程使其成为一个两步输入过程。

My ideas to obtain this info are to run a javascript function from python at that point when the user is at the URL because javascript react may be able to access the full URL. 我不知道该怎么做,还想知道是否还有其他方法可以获取 URL 的 access_token 部分? 请让我知道是否有任何其他信息可能会有所帮助。

这是 Spotify API 认证文档: https://developer.spotify.com/documentation/general/guides/authorization-guide/

编辑:感谢您使用“授权代码流程”而不是“隐式授予”流程的想法。 这似乎是通往 go 的方式。 但是,在我看来,区别在于使用请求方法并将 response_type 指定为“代码”,因此它不会以 hash 的形式返回。 它仍然无法正常工作(我得到“无法解析”,因为 URL 仍然有一个“#”),我怀疑我确实以它想要的方式指定了参数。 但我已经梳理过了,什么也没看到? 任何突出的东西::

from flask import Flask, request, jsonify, render_template, redirect, url_for
import requests
import json
app = Flask(__name__)

CLIENT_ID = "myclientid"
REDIRECR_URI="http://127.0.0.1:5000/callback" #this is the uri specified in my Spotify app

SCOPE='user-read-private%20user-read-playback-state%20user-top-read'
API_ENDPOINT = "https://accounts.spotify.com/authorize"

PARAMS = {  "client_id": CLIENT_ID, 
            "response_type": 'code', 
            "redirect_uri": REDIRECR_URI,
            "state": '123',
            "scope": SCOPE,
            "show_dialog": False
}
def userAuthURLBuilder(client_id, redirect_uri, scope):
    return "https://accounts.spotify.com/authorize?client_id={}&redirect_uri={}&scope={}&response_type=token&state=123".format(client_id, redirect_uri, scope)

builtUrl = userAuthURLBuilder(CLIENT_ID, REDIRECR_URI, SCOPE)

@app.route('/', methods=["GET"])
def getTester():
    r = requests.get(url = API_ENDPOINT, params=PARAMS)
    data = r.json()
    return data

@app.route('/<path:text>', methods=['GET', 'POST'])
def all_routes(text):
    if text.startswith('callback'):
        try:
            params = text.split('&code=')[1]
            return params
        except:
            return "couldn't parse" #this is what I'm currently getting 
    else:
        return "it errored"

您正在尝试使用 Spotify 的Implicit Grant Flow ,但这可能不是您想要的。 正如文档中所说:

隐式授权流适用于完全使用 JavaScript 实现并在资源所有者的浏览器中运行的客户端。

URL hash 值无法在服务器端访问 - 它们不包含在标头中。 The only way to obtain a URL hash value is from the client - using modern JavaScript you could get this withurl.hash .

但是,您真正应该做的是使用 Spotify 的Authorization Code Flow 这会将代码作为查询参数发送,而不是在 hash 后面发送,您可以使用request.args['code']获取它

更新

为了响应您更新的问题,您应该使用request.args来获取 URL 查询参数,而不是尝试解析出实际的字符串。 像这样的东西应该工作:

@app.route('/callback', methods=['GET', 'POST'])
def all_routes(text):
  if request.method == 'GET':
    try:
      params = request.args
      if params and params['code']:
        return params['code']
      else:
        return params['error']
    except:
      return "couldn't parse"
  else:
    # not sure why you would use POST here
    return

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM