GAE/Python - 从主类重定向有效,但从调用方法无效
当我从main.py进行重定向时,它可以正常工作,但当我尝试在它调用的一个方法内部进行重定向时,什么都没有发生。没有错误,程序就是不做任何事情。
main.py
from githubauth import GetAuthTokenHandler
class AuthUser(webapp2.RequestHandler):
"""
If no environment variable exists with the access token in it,
auth the user as an admin. If it does exist, auth them as a regular
user.
"""
def get(self):
if not ACCESS_TOKEN:
# No access token exists, auth user as admin
get_auth_token = GetAuthTokenHandler()
get_auth_token.get()
githubauth.py
import webapp2
class GetAuthTokenHandler(webapp2.RequestHandler):
"""Redirect users to github to get an access request token."""
def get(self):
self.redirect('http://api.github.com/authorize')
3 个回答
要让RequestHandler正常工作,你需要用一个请求和一个响应来创建它。也就是说,在一个处理方法里创建一个RequestHandler,然后再调用它的方法,这样做其实有点奇怪。
这要看你用Github做什么样的授权,主要有两种方式:OAuth令牌授权和网页应用流程。
OAuth令牌授权
如果你使用的是OAuth授权,那就不需要创建一个请求处理程序来获取Github的授权令牌。请求处理程序是用来处理你服务器上特定网址的,而这个任务你可以用urlfetch()
来完成。
整个流程大概是这样的:
import webapp2
from google.appengine.api import urlfetch
def getAuthToken():
github_auth_url = "http://api.github.com/authorizations"
result = urlfetch.fetch(github_auth_url)
return result
class AuthUser(webapp2.RequestHandler):
def get(self):
if not ACCESS_TOKEN:
# No access token exists, auth user as admin
get_auth_token = getAuthToken()
# do something with your token...
重定向授权(网页应用流程)
如果你申请了一个客户端ID,并且想要作为独立的网页应用被用户授权,那么这个过程比前面提到的要复杂一些:
- 把用户重定向到请求Github访问
- Github会把用户重定向回你的网站
如果你对这个流程不太了解,可以看看 Github OAuth - 网页应用流程
接下来我们看看如何在Google App Engine中实现这个流程。
把用户重定向到请求Github访问
这一部分就是你示例中的内容,简单来说就是把用户重定向到授权网址,并带上指定的参数。
from urllib import urlencode
class AuthUser(webapp2.RequestHandler):
def get(self):
# ... do something ...
# Github configuration
github_client_id = "Your github client id..."
github_redirect_url = "Your url for github redirecting users back to your GAE"
github_scope = "Gtihub scopes...."
github_authorize_url = "http://github.com/login/oauth/authorize"
github_authorize_parameters = {
'client_id': github_client_id,
'redirect_url': github_redirect_url,
'scope': github_scop
}
if not ACCESS_TOKEN:
# if no access_token found on your site, redirect users to Github for authorization
url_to_redirect = "%s?%s" % (github_authorize_url, urlencode(github_authorize_parameters))
self.redirect(url_to_redirect)
Github把用户重定向回你的网站
Github会根据之前的参数redirect_url
把用户重定向回你的网站,所以你需要准备另一个请求处理程序来接收Github的重定向。
(你可以在同一个请求处理程序中处理,但这样会让代码变得混乱)
从第一步重定向回来的信息会包含一个参数code
,你需要这个参数来换取访问令牌。
from urllib import urlencode
class GithubRequestHandler(webapp2.RequestHandler):
def get(self):
# this handler need to be bind to redirect_url
# get authentication code
github_code = self.request.get('code')
# prepare data to exchange access token
github_token_url = "https://github.com/login/oauth/access_token"
github_token_parameters = {
'client_id': 'Your Github client id',
'client_secret': 'Your Github client secret',
'code': github_code}
# exchange access token
data = urlfetch.fetch(github_token_url, payload=urlencode(github_token_parameter), method='POST')
# data will perform in the following form:
# access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&scope=user%2Cgist&token_type=bearer
# extract access_token from the string
# save the access_token to user's model
附注
这段代码有点像你应用流程的模拟,实际运行时需要一些调整才能在生产环境中使用 :)
你想创建一个 webapp2 的请求处理器,但这样做是不行的。get_auth_token 不是一个 WSGI 的 webapp2 处理器实例。如果你不想改动 githubauth.py,那你就得改动你的 main.py。
class AuthUser(webapp2.RequestHandler):
def get(self):
if not ACCESS_TOKEN:
self.redirect(to your GetAuthTokenHandler)
如果你没有访问令牌,这样做会导致出现两个重定向。