Stormpath Logo
  • Blog

The Stormpath API shut down on August 17, 2017. Thank you to all the developers who have used Stormpath.

Hosted Login and API Authentication for Python Apps

by Randall Degges | November 6, 2014 |

  • Python

If you’re building Python web apps — you might have heard of our awesome Python libraries which make adding users and authentication into your web apps way easier:

  • python-stormpath
  • flask-stormpath
  • django-stormpath

What you probably didn’t know, however, is that our Python library just got a whole lot more interesting. Last week we made a huge release which added several new features.

The Basics

Since the beginning of time, our Python library has made creating user accounts, managing groups and permissions, and even storing profile information incredibly easy.

If you’re not familiar with how this works, take a look at the code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from stormpath.client import Client
 
client = Client(id='xxx', secret='xxx')
 
# Create an app.
app = client.applications.create({'name': 'myapp'}, create_directory=True)
 
# Create a user.
account = app.accounts.create({
    'given_name': 'Randall',
    'surname': 'Degges',
    'email': '[email protected]',
    'password': 'iDONTthinkso!222',
    'custom_data': {
        'secret_keys': [
            'blah',
            'woot',
            'bankstuff',
        ],
    },
})
 
# Create a group.
admins_group = app.groups.create({ 'name': 'admins' })
 
# Add the user to the group.
account.add_group(admins_group)
 

The code above creates a new user account, stores some account information, creates a group, and puts that user into the group — all in a few lines of code.

With Stormpath, all users are stored on Stormpath’s servers, where we encrypt the user information and provide abstractions and libraries to make handling authentication as simple as possible.

NOTE: You can install our library via PyPI, the Python package manager: pip install stormpath.

ID Site

A while back, some of us over here were chatting about ways to make authentication better, and the idea of ID Site was born.

What if, as a developer, you didn’t have to render views and templates to perform common authentication tasks?

What if, all you had to do was redirect the user to some sub-domain (like login.yoursite.com), and all of the authentication and registration stuff would be completely taken care of for you?

Furthermore — what if you could fully customize the way your login pages look using all the latest-and-greatest tools?

It would be totally awesome, right?

Well — that’s what ID Site does!

ID Site is a hosted product we run that allows you to easily handle complex authentication rules (including SSO, social login, and a bunch of other stuff), while providing users a really nice, clean experience.

And as of our latest Python release — you can now use it really easily!

To redirect a user to your ID Site to handle authentication stuff, all you need to do is generate a secure URL using our helper functions:

1
2
3
url = app.build_id_site_redirect_url('http://login.mysite.com/redirect')
# Then you'd want to redirect the user to url.
 

By default, the normal login page looks something like this (depending on whether or not you have social login and other features enabled):

id-site-python

After the user signs in, they’ll be redirect back to whatever URL you specify as a parameter above — then you can create a user session and persist the user’s information — this way you know they’ve been logged in.

Again — this is super easy.

Assuming you’re writing code to handle the redirect, you’d do something like this:

1
2
3
result = app.handle_id_site_callback(request)
# result.account is the user's account.
 

Bam! And just like that, you can register, login, and logout users.

API Keys and Authentication!

Let’s say you’re building a REST API, and need to ensure only certain users have access to the API. This means you’ve got to generate API keys for each user, and authenticate incoming API requests.

Depending on the tools and libraries you’re using, this could be either a very simple or very painful task.

With our latest Python release, you can now generate as many API keys as you want for each of your users. This means building API services just got a wholeeeeee lot easier:

1
2
3
4
# Generate an API key for a user.
key = account.api_keys.create()
print key.id, key.secret
 

Each API key has two parts:

  • An id (similar to a username).
  • A secret (similar to a password).

Once you’ve generated an API key for a user, and given that key TO the user, they can then use their API key to authenticate against your API service using either:

  • HTTP Basic Authentication, or
  • OAuth2

To authenticate a user via HTTP Basic Authentication, you write code that looks like this:

1
2
3
4
5
6
7
8
9
10
11
# Assuming the user sent you their API credentials properly, by passing in
# the `headers` option our library will handle authentication for you.
result = app.authenticate_api(
    allowed_scopes=None,
    http_method=None,
    uri=None,
    body=None,
    headers=request.headers
)
# result.account is now the user's account object!
 

The above code will work properly when a developer sends an authenticated API request of the form:

1
2
3
4
5
GET /troopers/tk421/equipment
Accept: application/json
Authorization: Basic MzRVU1BWVUFURThLWDE4MElDTFVUMDNDTzpQSHozZitnMzNiNFpHc1R3dEtOQ2h0NzhBejNpSjdwWTIwREo5N0R2L1g4
Host: api.trooperapp.com
 

For OAuth flows, things are equally simple — firstly, you need to request an OAuth token by exchanging your API keys for an OAuth token:

1
2
3
4
5
6
7
8
POST /oauth/token
Accept: application/json
Authorization: Basic MzRVU1BWVUFURThLWDE4MElDTFVUMDNDTzpQSHozZitnMzNiNFpHc1
Content-Type: application/x-www-form-urlencoded
Host: api.trooperapp.com
 
grant_type=client_credentials
 

When this request is made, on the server-side you can generate a token by calling the authenticate_api method:

1
2
3
4
5
6
7
8
9
result = app.authenticate_api(
    allowed_scopes=None
    http_method='POST',
    uri='/blah',
    body=request.body,
    headers=request.headers
)
# result.token is now the user's OAuth token object!
 

From this point on, the developer can now pass that token as their credentials:

1
2
3
4
5
GET /troopers/tk421/equipment
Accept: application/json
Authorization: Bearer 7FRhtCNRapj9zs.YI8MqPiS8hzx3wJH4.qT29JUOpU64T
Host: api.trooperapp.com
 

And if you want to secure an API endpoint with OAuth, you just use the same authenticate_api method as before:

1
2
3
4
5
6
7
8
9
result = app.authenticate_api(
    allowed_scopes=None
    http_method='POST',
    uri='/blah',
    body=request.body,
    headers=request.headers
)
# result.token is now the user's OAuth token object!
 

Cool, right?!

Using our new API stuff, you can easily build out a public (or private) facing API service complete with both HTTP Basic Authentication and OAuth2.

Github and LinkedIn

Lastly, we’ve also added two brand new social providers to platform: Github and LinkedIn.

This means that if you want to allow your web users to log into your app via:

  • Google
  • Facebook
  • Github or
  • LinkedIn

You can easily do so with just a few lines of code!

Future Stuff

We’re still working really hard to improve our Python library — we’re cleaning up our docs, simplifying our internal APIs, and doubling down on our efforts to make it the most awesome, simple, and powerful tool out there.

If you have any feedback (good or bad), please send us an email! We’d love hear from you: [email protected]

Explore the Topic

  • .NET
  • General
  • Java
  • Javascript
  • Mobile
  • Node
  • PHP
  • Python
  • REST API

Share a Post

0
0
0
0
0
0
0
0
Support: [email protected]
Copyright 2017 Stormpath