尝试使用stormpath实现基于oauth / token的登录

时间:2016-05-22 13:25:08

标签: python login oauth stormpath

我的代码:

            from stormpath.api_auth import ApiRequestAuthenticator
            import base64

            application = app.stormpath_manager.application
            account = application.accounts[0] # random account
            new_api_key = account.api_keys.create()
            authenticator = ApiRequestAuthenticator(application)
            uri = 'dont_care'
            http_method = 'GET'
            headers = {
                'Authorization': 'Basic ' + base64.b64encode(new_api_key.id + ":" + new_api_key.secret)
            }
            result = authenticator.authenticate(headers=headers, http_method=http_method, uri=uri, body={}, scopes=[])
            print result.api_key #<ApiKey href=https://api.stormpath.com/v1/apiKeys/bla_bla>
            print result.account # bla_bla@gmail.com
            print result.token # None

我错过了什么? 我的代码基于this part of the documentation.

2 个答案:

答案 0 :(得分:0)

Heyo,我是这个图书馆的作者,所以我想跳到这里=)

你想做的事情是这样的。我假设您尝试使用基于用户名/密码的登录而不是API密钥登录,对吗? (EG:你有一个像Angular这样的前端客户端,或者是一个提出这些请求的移动应用程序吗?)

如果是这样,您可以使用我的示例来完成您想要的任务:

from os import environ

from stormpath.api_auth import PasswordGrantAuthenticator
from stormpath.client import Client


STORMPATH_CLIENT_APIKEY_ID = environ['STORMPATH_CLIENT_APIKEY_ID']
STORMPATH_CLIENT_APIKEY_SECRET = environ['STORMPATH_CLIENT_APIKEY_SECRET']
STORMPATH_APPLICATION_NAME = environ['STORMPATH_APPLICATION_NAME']
STORMPATH_USER_EMAIL = environ['STORMPATH_USER_EMAIL']
STORMPATH_USER_PASSWORD = environ['STORMPATH_USER_PASSWORD']


client = Client(id=STORMPATH_CLIENT_APIKEY_ID, secret=STORMPATH_CLIENT_APIKEY_SECRET)
application = client.applications.query(name=STORMPATH_APPLICATION_NAME)[0]


authenticator = PasswordGrantAuthenticator(app=application)
result = authenticator.authenticate(STORMPATH_USER_EMAIL, STORMPATH_USER_PASSWORD)

if result:
    print('Access Token: {}'.format(result.access_token))
    print('Refresh Token: {}'.format(result.refresh_token))
else:
    print('Invalid credentials supplied.')

答案 1 :(得分:0)

我实际上使用ApiRequestAuthenticator来完成

def get_api_key(self, app, user_data):

    self.init_authenticator()

    email = user_data['email']
    if not hasattr(self, 'cloud_directory'):
        self.cloud_directory = app.stormpath_helper.get_cloud_directory(APP_NAME + '-' +  env)

    if self.accounts.get(email) is None:
        account = self.cloud_directory.accounts.search({'email': email})
        if account is None:
            raise Exception('failed to find account')

        self.accounts[email] = account[0]

    if self.api_keys.get(email) is None:
        api_key = self.accounts[email].api_keys.create()
        self.api_keys[email] = api_key

    return self.api_keys[email]


# init authenticator to stormpath api to validate access tokens
def init_authenticator(self):
    if not hasattr(self, 'application'):
        self.application = self.app.stormpath_manager.application

    if not hasattr(self, 'authenticator'):
        self.authenticator = ApiRequestAuthenticator(self.application)


def get_client_access_token(self, app, user_data):
    api_key = self.get_api_key(app, user_data)

    uri = 'bla_dont_care.com?grant_type=client_credentials'
    http_method = 'GET'
    headers = {
        'Authorization': 'Basic ' + base64.b64encode(api_key.id + ":" + api_key.secret)
    }
    result = self.authenticator.authenticate(headers=headers, http_method=http_method, uri=uri, body={}, scopes=[])
    if result:
        client_token = result.token.token
    else:
        raise Exception('Invalid or not authenticated request.')

并且登录时我使用:

def is_token_valid(request, authenticator):
    uri = 'bla_dont_care.com'
    # headers = {
    #     'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2FwaS5zdG9ybXBhdGguY29tL3YxL2FwcGxpY2F0aW9ucy9WSmlYRFdUV25ZZE5nckZlOUJvSTMiLCJpYXQiOjE0NjM5ODYxNTAsInN1YiI6IjVHWk03REpWNTFRSkhDWk41WENQMDEwRjQiLCJleHAiOjE0NjM5ODk3NTAsInNjb3BlIjpudWxsfQ.MTxQ2AzhlCkOtws4cnwLdrUhLEUGHpMOIATbSX9AeGw'
    # }
    result = authenticator.authenticate(headers=request.headers, http_method='GET', uri=uri, body={}, scopes=[])

    if result is None:
        return False, None

    is_valid = result.account is not None
    return is_valid, result.account