{"id":15903446,"url":"https://github.com/vfdev-5/drfso2_test","last_synced_at":"2025-04-02T20:15:19.728Z","repository":{"id":149000926,"uuid":"44258135","full_name":"vfdev-5/DRFSO2_Test","owner":"vfdev-5","description":"A test of Django-rest-framework-social-oauth2 application","archived":false,"fork":false,"pushed_at":"2015-10-21T14:57:09.000Z","size":160,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-08T10:43:51.492Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vfdev-5.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-14T15:42:46.000Z","updated_at":"2017-02-20T16:07:24.000Z","dependencies_parsed_at":"2023-04-10T17:43:14.890Z","dependency_job_id":null,"html_url":"https://github.com/vfdev-5/DRFSO2_Test","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vfdev-5%2FDRFSO2_Test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vfdev-5%2FDRFSO2_Test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vfdev-5%2FDRFSO2_Test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vfdev-5%2FDRFSO2_Test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vfdev-5","download_url":"https://codeload.github.com/vfdev-5/DRFSO2_Test/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246884766,"owners_count":20849554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-06T12:01:56.484Z","updated_at":"2025-04-02T20:15:19.706Z","avatar_url":"https://github.com/vfdev-5.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# A test of [django-rest-framework-social-oauth2](https://github.com/PhilipGarnero/django-rest-framework-social-oauth2/blob/master/rest_framework_social_oauth2)\n\n\n## Idea :\n- Rest Api with open/protected resources :\n    - Available entry points :\n        - open : /api/, /api/register/\n        - protected : /api/protected/\n- Users :\n    - local\n    - social\n- Client applications: a) local website, b) mobile app (curl + web browser)\n    - register new local user\n    - access protected resources\n\n## Server backend\n- OAuth2 application : client type is 'Confidental' and authorization grant type is 'Resource owner password-based'\n\n\n## Mobile app\n\n### 1) Obtain the access token for a github user\nOpen web browser with URL :\n```\n/auth/login/github/?next=/profile/\n```\nAuthorize the usage of the user information by the server.\nThe final redirection will contain the parameters: access_token, backend, expires\n```\n/profile/?access_token=\u003ctoken\u003e\u0026backend=\u003cbackend\u003e\u0026expires=\u003cexpires\u003e\n```\nNote: a new user will be created automatically\n\n### 2.1) Create new local user\nSend POST request to '/api/register/' with parameters :\n- username=\u003cusername\u003e\n- password=\u003cpassword\u003e\n- email=\u003cemail\u003e\n\n```\ncurl -X POST -d \"username=${username}\u0026password=${password}\u0026email=${email}\" /api/register/\n```\n\nNote: user is identified by its unique username\n\n### 2.2) Obtain the access token for a local user\nSend POST request to '/auth/token/' with parameters :\n- username=\u003cusername\u003e\n- password=\u003cpassword\u003e\n- grant_type=password\n- client_id=\u003cclient_id\u003e\n- client_secret=\u003cclient_secret\u003e\n\n```\ncurl -X POST -d \"client_id=${client_id}\u0026client_secret=${client_secret}\u0026grant_type=password\u0026username=${username}\u0026password=${password}\" ${URL}\n```\n\n### 3) Access api protected resources\n#### For a local user :\nInsert \"Authorization: Bearer \u003ctoken\u003e\" to the header and send a request to the url\n```\ncurl -v -H \"Authorization: Bearer \u003ctoken\u003e\" /api/protected/\n```\n\n#### For a social network user :\nInsert \"Authorization: Bearer github \u003ctoken\u003e\" to the header and send a request to the url\n```\ncurl -v -H \"Authorization: Bearer github \u003ctoken\u003e\" /api/protected/\n```\n\n## Local web site\n\n### 1) Obtain the access token for a github user\nFor that user need to login :\nHtml part :\n```\n\u003ca href=\"/auth/login/github/?next=/\"\u003eLogin with Github\u003c/a\u003e\n```\nDjango part :\nIt is possible to insert access token and backend as templates to views.\n\n```\nuser = request.user\nif user.is_authenticated:\n    try:\n        # get the last login provider\n        provider = request.session['social_auth_last_login_backend']\n        social = user.social_auth.get(provider=provider)\n        access_token = social.extra_data['access_token']\n        expires = social.extra_data['expires']\n    except KeyError:\n        # This is a local user without social network backend\n\n\ncontext = {\n    \"access_token\": access_token,\n    \"provider\": provider,\n    \"expires\": expires,\n}\n```\n\n### 2.1) Create new local user\nIt can be done with a simple html form\n\n### 2.2) Obtain the access token for a local user\n\nFor that user need to login : configure url to django.contrib.auth.views.login with a custom template html\n```\nurl(r'^login/$', views.login, {'template_name': 'login.html'}, name='login'),\n```\nand redirect the link to the main page.\n\nIn the main page django view code to get access token should be separated for social and local users\n```\ntry:\n    provider = request.session['social_auth_last_login_backend']\n    social = user.social_auth.get(provider=provider)\n    access_token = social.extra_data['access_token']\n    expires = social.extra_data['expires']\nexcept KeyError:\n    print \"This is an ordinary user without social network backend\"\n    # Issue an access_token\n    token = get_or_create_token(user)\n    if token is not None:\n        access_token = token.token\n        provider = None\n        expires = token.expires\n```\n\nIn the method 'get_or_create_token' find not expired access tokens using 'oauth2_provider.models.AccessToken' :\n```\napplication = Application.objects.get(name=\"Local OAuth2 Server with Password\")\ntokens = AccessToken.objects.filter(user=user, expires__gt=datetime.now(), application=application)\n```\nif no tokens found then create one with a refresh token\n\n### 3) Access api protected resources\nThis can be done using ajax or whatever other tools that can send requests to the urls. For example, using jquery $.ajax :\n#### For a local user :\n```\nvar headers = {\"Authorization\": \"Bearer \" + token};\nvar request = $.ajax({\n    url: '/api/protected/',\n    method: \"GET\",\n    headers: headers\n}).done(function( msg ) {\n    // Do something with the resulting message object\n});\n```\n#### For a social network user :\n```\nvar headers = {\"Authorization\": \"Bearer github \" + token};\nvar request = $.ajax({\n    url: '/api/protected/',\n    method: \"GET\",\n    headers: headers\n}).done(function( msg ) {\n    // Do something with the resulting message object\n});\n```\n\n\n\n\n## Open questions :\n\n- How to issue a token for a local user\n-\u003e Create token using Application, AccessToken etc\n\n- Mobile part should display only its own access_tokens\n-- need convert 3rdparty tokens to local tokens\n\n- How to use refresh tokens\n- How to remove expired tokens, https://github.com/evonove/django-oauth-toolkit/issues/148\n\n- Mobile / API / Django / 3rd party OAuth workflow, http://stackoverflow.com/questions/27051209/oauth2-token-authentication-using-django-oauth-toolkit-and-python-social-auth\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvfdev-5%2Fdrfso2_test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvfdev-5%2Fdrfso2_test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvfdev-5%2Fdrfso2_test/lists"}