Usage Example

Full Example

socialauth uses JSON web tokens to store intermediate data within the OAuth flow. This means the client holds on to necessary state — not the server. The server remains stateless and does not use sessions.

This Flask example uses cookies to store the token on the client.

socialauth is designed to handle both the start and completion of the OAuth flow (user’s initial request, callback from provider) in the same route with the same socialauth.http_get_provider() call.

 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# This is a usage example with Flask.
#
# For details and documentation, check out:
# https://socialauth.readthedocs.org/

import os

import dotenv
import jwt
from flask import (
    Flask, request, current_app, redirect,
    jsonify, make_response, abort
)

import socialauth


app = Flask(__name__)


@app.route('/whoami')
def whoami():
    # User IDs are likely protected values, so exposing this value wouldn't
    # be typically recommended in production.
    res = jwt.decode(request.cookies.get('jwt'), current_app.secret_key)
    return res.get('user_id')


# GET /auth/facebook?login=start
# GET /auth/twitter?login=start
@app.route('/auth/<provider>')
def authenticate(provider):
    res = socialauth.http_get_provider(
        provider,
        request.base_url,           # Callback URL
        request.args,               # GET parameters/query string
        current_app.secret_key,
        request.cookies.get('jwt')  # Currently stored token
    )

    if res.get('status') == 302:
        resp = make_response(redirect(res.get('redirect')))
        if res.get('set_token_cookie') is not None:
            resp.set_cookie('jwt', res.get('set_token_cookie'), httponly = True)

        return resp

    if res.get('status') == 200:
        resp = make_response(jsonify({ 'status': 'success' }))

        token = jwt.encode(
            { 'user_id': res.get('provider_user_id') },
            current_app.secret_key,
            algorithm = 'HS256'
        )
        resp.set_cookie('jwt', token, httponly = True)

        return resp

    # Something has gone very wrong. This should not happen.
    abort(400)


if __name__ == '__main__':
    dotenv.load_dotenv('.env')
    app.secret_key = os.urandom(24)
    app.debug = True
    app.run(host = '0.0.0.0')