I'm starting the integration of an app that will serve OAuth authentication method in a Django project. Django OAuth Toolkit appeared as a good solution, however the documentation was a little confused to me and I had a hard way of testing to understand how it works.
For this tutorial I'm using
Django==1.9.1
Flask==0.10.1
django-cors-headers==1.1.0
django-oauth-toolkit==0.10.0
The Server
First of all, create a Django project:
django-admin.py startproject my_oauth_server
After that, let's follow the steps at the oficial tutorial (assuming you have already installed the packages above):
Add oauth2_provider and corsheader in your settings.py
INSTALLED_APPS = { # ... 'oauth2_provider', 'corsheaders', }
Add the toolkit urls:
urlpatterns = patterns( '', url(r'^admin/', include(admin.site.urls)), url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')), # ... )
And the middleware:
MIDDLEWARE_CLASSES = ( # ... 'corsheaders.middleware.CorsMiddleware', # ... )
And add this in settings:
CORS_ORIGIN_ALLOW_ALL = True
Now let's create the authentication system for our Django:
django-admin.py startapp my_authentication
By the simplest way, create the view:
from django.http.response import HttpResponse, HttpResponseRedirect from django.shortcuts import render from django.contrib.auth import authenticate, login, logout # Create your views here. def login_page(request): next_page = request.GET.get('next', '/') if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) login(request, user) return HttpResponseRedirect(next_page) return render(request, 'login.html', {'next': next_page}) def logout_page(request): logout(request) return HttpResponseRedirect('/') def home(request): return HttpResponse("Logged in: %s" % request.user.is_authenticated())
Now create the template login.html:
<form method="post"> {% csrf_token %} <input type="hidden" name="next" value="{{ next }}" /> <p> username <input type="text" name="username" /> </p> <p> password <input type="password" name="password" /> </p> <button type="submit" >Login</button></form>
Actually, it's stupid simple, just to have an exemple. The "next" input receives the value from the url. This is required to were go after login.
Finally, add your app urls:
from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls),
url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
url(r'^$', 'authorization_server.views.home'),
url(r'^accounts/login/$', 'authorization_server.views.login_page'),
url(r'^logout/$', 'authorization_server.views.logout_page'),]
Just run the migrate command and create an user to authorize using oauth. Create an an app at:
/o/applications. Copy the client id and client secret. Put the redirect url to /consumer at your address (in my case, the consumer will run at port 9100
The consumer
I got this exemple and applyed to my project. you can see the code bellow:from flask import Flask from flask import request app = Flask(__name__) CLIENT_ID = "Vkh2wibaQZLaxrvhYQUq8I5WWdqRLmQJXQc2YxPB"CLIENT_SECRET = "czsU5umPX2mrLqKTlLV6YNSgbPLQKxdp2WsOlWJkIYJjXP4rSrnwEwZJlAkCo7fjlCCPo3ReLMGazjeMWO5ujtjAJEOLIsTWcrE18PxwiioQMOQxTvEQQliMSCOLxEnl"REDIRECT_URI = "http://localhost:9100/consumer" from flask import Flask app = Flask(__name__) # Left as an exercise to the reader.# You may want to store valid states in a database or memcache,# or perhaps cryptographically sign them and verify upon retrieval.def save_created_state(state): pass def is_valid_state(state): return True import requests import requests.auth def get_token(code): client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET) post_data = {"grant_type": "authorization_code", "code": code, "redirect_uri": REDIRECT_URI} response = requests.post("http://localhost:9000/o/token", auth=client_auth, data=post_data) token_json = response.json() return token_json["access_token"] from flask import abort, request @app.route('/consumer/') def reddit_callback(): error = request.args.get('error', '') if error: return "Error: " + error state = request.args.get('state', '') if not is_valid_state(state): # Uh-oh, this request wasn't started by us! abort(403) code = request.args.get('code') # We'll change this next line in just a moment return "got a code! %s" % code if __name__ == '__main__': app.run(debug=True, port=9100) def get_username(access_token): headers = {"Authorization": "bearer " + access_token} response = requests.get("http://localhost:9000/user_data", headers=headers) me_json = response.json() return me_json['username']
Run the flask server. Here I used the port 9000 to the server and 9100 for the consumer. The authentication url:
http://localhost:9000/o/authorize/?response_type=code&state=random_state_string&client_id=Vkh2wibaQZLaxrvhYQUq8I5WWdqRLmQJXQc2YxPB
Use the right attribute values for client id. With this you can log users in your application with oauth and consume that.
Nenhum comentário:
Postar um comentário