I am creating a website using html as a frontend and python as a backend using EVE framework. I have enabled token authentication for my usersRESTful Account Management. But when I pass the values to the EVE framework it gives me a 401.
var login = function (loginData) {
var deferred = $q.defer();
$http.post(appConfig.serviceUrl + 'user',{data:loginData})
here the loginData holds the username and password of my user from the html page this piece of code is inside a .js file.
My api.py holds the following authentication code.
class RolesAuth(TokenAuth):
def check_auth(self, token, allowed_roles, resource, method):
# use Eve's own db driver; no additional connections/resources are used
accounts = app.data.driver.db['user']
lookup = {'token': token}
if allowed_roles:
lookup['roles'] = {'$in': allowed_roles}
account = accounts.find_one(lookup)
return account
def add_token(documents):
# Don't use this in production:
# You should at least make sure that the token is unique.
for document in documents:
document["token"] = (''.join(random.choice(string.ascii_uppercase)
for x in range(10)))
My problem is as soon as the api.py is run it asks to provide proper credentials. How can i send the token directly to the auth mechanism so that it lets me access the db.
How will you suggest me to get rid of the authentication alert box.
I want the token to be automatically sent to the api.
If suppose I use basic authentication how can I send the username and password values directly and validate it? Without having the browser pop-up box asking for username and password
Thanks in advance.
Does it work with curl ? Refer to this question
Also, refer to this and this thread on the mailing list.
Related
I want to call my own API in a custom view I wrote. Normally I use JWT authentication with my API calls. In this specific view though, I'd like to use a different authentication.
I want to enable logged in users to make a successful get call (without a token). Not logged in users should not be able to make that call. I tried this with Basic Authentication and Session Authentication but don't really get it tow work.
Here is my view that makes the API call:
def visualize_buildings(request, id):
passed_id = id
endpoint = 'linktomyendpoint' + str(passed_id)
response = requests.get(endpoint)
building_group_data = response.json()
# print(building_group_data)
if 'buildings' in building_group_data:
building_data = building_group_data['buildings']
context = {'building' : building_data}
return render(request, 'building_group_visualize_api.html', context)
else:
return HttpResponseNotFound("Ups. We are sorry but no Building Group was found with that id")
Here my API view:
class BuildingGroupRetrieveAPIView(RetrieveAPIView):
authentication_classes = [JSONWebTokenAuthentication,
SessionAuthentication, BasicAuthentication]
serializer_class = BuildingGroupSerializer
queryset = BuildingGroup.objects.all()
The view works with if I send a token in the headers. But how can I use Session Authentication with that? I tried getting username and password from the request and then pass it to the API call. But that doesn't work because I can't decode the password from the request (which makes sense).
So I tried to follow this: https://2.python-requests.org/en/master/user/advanced/ but I still can't authenticate my request.
Can anyone point me into the right direction? Help is very much appreciated! Thanks in advance!
Session ids are saved as a cookie on the user's device and they will be sent to the server as a header name Cookie. So if you want to use cookies instead of the JWT token then you should send your request with the session id as a cookie header.
This is the header that lets Django know your session-id when you visit the site directly:
Cookie: csrftoken=some-csrf-token; sessionid=your-session-id
Now to make your request contain something like that:
cookies = {'sessionid': 'your-session-id'}
response = requests.get(endpoint, cookies=cookies)
Note that Django might still through an error for csrf token based on your settings.
You can find your session-id on your browser. If you don't know where and how to access them, just google it. it's different based on the browser you use.
My website hosts a lot of APIs(CRUDs) using DJR. I am using DJR Token based authentication and for testing I would add this header to postman
Key : Authorization
value : Token 826fdf3067b07afdf9edd89a6c9facd9920de8b8
and Django Rest Framework would easily be able to authenticate the user.
Now I inlcuded Django channels constantly 1.1.5 and wanted to know how I could do token based authentication. I read this post and it suggests that I copy this mixin to the project. I just started with Django-channels and am not sure how to include that mixin to my code. Currently I have something like this
#channel_session_user_from_http
def ws_connect(message):
user = message.user
message.reply_channel.send({"accept": True}) #Send back Acceptance response.
#channel_session_user
def chat_join(message):
user = message.user #Get authenticated user
I have the following two questions
1-How do I include that mixin in my current project ? I know you include mixins in classes using class classname(SomeMixin). How would I go about including this mixin into my code ?
2-Will I need to include an authentication token in my json message that I send to the websocket ?
Any suggestions would be great.
`
I have read multiple tutorials on authentication but I am just as confused. I am trying to log a user in using an html form on the client device, which means I'm not using Django templates. Does it work like the following?
I send a post to rest backend with username, password combo
Django rest checks to see if valid user, and sends token back?
I save token in local storage, and send with every request of user?
What do I send from the front end to make this happen?
Yes, send a post request to a RESTful backend with username and password combo
Django authenticates the username and password and logs the user in which sets a sessionid associated with the user which I believe you are referring to as a token. This is done via the login() method. https://docs.djangoproject.com/en/dev/topics/auth/default/#django.contrib.auth.login
Normally Django would set a sessionid as a coookie or session variable on the client's machine, but I'd imagine you could save it in local storage and then retrieve it each time and validate it's a valid sessionid on each request but it's easier to just let Django's middleware take care of everything by just using sessions.
I have a django app and I create API for mobile app. When it comes to user authentication I simple gets login + pass and do standard django login stuff. When user is logged in I generate a token, save it and provide to the mobile app.
Now it comes to Facebook and I would like to implement python-social-auth library. I do know how to implement it for standard web, it's really trivial. But I have no idea, how to implement it into my mobile API and how to incorporate there my token stuff.
Just thinking...
Is there a possibility to do programatical auth so I would be able to create API method and call the social auth stuff from there? But how about the "Allow access to XY app to your profile" page on facebook side?
Any advice helps. Thank you in advance.
The documentation describes how you can simply provide the access_token to authenticate/create a user.
from django.contrib.auth import login
from social.apps.django_app.utils import psa
# Define an URL entry to point to this view, call it passing the
# access_token parameter like ?access_token=<token>. The URL entry must
# contain the backend, like this:
#
# url(r'^register-by-token/(?P<backend>[^/]+)/$',
# 'register_by_access_token')
#psa('social:complete')
def register_by_access_token(request, backend):
# This view expects an access_token GET parameter, if it's needed,
# request.backend and request.strategy will be loaded with the current
# backend and strategy.
token = request.GET.get('access_token')
user = request.backend.do_auth(request.GET.get('access_token'))
if user:
login(request, user)
return 'OK'
else:
return 'ERROR'
When I make a redirect from main.py, it works, but when I try to redirect from within a method that it calls, nothing happens. There is no error, the program simply does nothing.
main.py
from githubauth import GetAuthTokenHandler
class AuthUser(webapp2.RequestHandler):
"""
If no environment variable exists with the access token in it,
auth the user as an admin. If it does exist, auth them as a regular
user.
"""
def get(self):
if not ACCESS_TOKEN:
# No access token exists, auth user as admin
get_auth_token = GetAuthTokenHandler()
get_auth_token.get()
githubauth.py
import webapp2
class GetAuthTokenHandler(webapp2.RequestHandler):
"""Redirect users to github to get an access request token."""
def get(self):
self.redirect('http://api.github.com/authorize')
It depends on what kind of authorization you're doing with Github, there are two ways to do that, OAuth token authorization and Web Application Flow.
OAuth Token Authorization
If you're doing OAuth authorization, you don't have to create a request handler to fetch Github auth token, request handler is for serving specific url on your server, for this kind of task, you should use urlfetch().
So the whole flow should be like the following code:
import webapp2
from google.appengine.api import urlfetch
def getAuthToken():
github_auth_url = "http://api.github.com/authorizations"
result = urlfetch.fetch(github_auth_url)
return result
class AuthUser(webapp2.RequestHandler):
def get(self):
if not ACCESS_TOKEN:
# No access token exists, auth user as admin
get_auth_token = getAuthToken()
# do something with your token...
Redirect Authorization (Web Application Flow)
This is the case if you have applied a client id, and want to be authorized by users as a standalone web application, the steps of this kind authorization is more complicated than former one:
Redirect users to request GitHub access
GitHub redirects back to your site
If you don't know about this flow, take a look at Github OAuth - Web Application Flow
Let's see how could we do within Google App Engine
Redirect users to request Github access
This is the part which involved in your sample, simply redirect user to the authorize url with specified parameters
from urllib import urlencode
class AuthUser(webapp2.RequestHandler):
def get(self):
# ... do something ...
# Github configuration
github_client_id = "Your github client id..."
github_redirect_url = "Your url for github redirecting users back to your GAE"
github_scope = "Gtihub scopes...."
github_authorize_url = "http://github.com/login/oauth/authorize"
github_authorize_parameters = {
'client_id': github_client_id,
'redirect_url': github_redirect_url,
'scope': github_scop
}
if not ACCESS_TOKEN:
# if no access_token found on your site, redirect users to Github for authorization
url_to_redirect = "%s?%s" % (github_authorize_url, urlencode(github_authorize_parameters))
self.redirect(url_to_redirect)
Github redirects users back to your site
Github will redirect users back to your site based on the previous parameter redirect_url, so you will have to prepare another request handler for receiving redirection from Github.
(You can do this is the same request handler, but it will mess your code)
The redirection back from the step 1 will contains one parameter, code, you will need it to exchange for an access token.
from urllib import urlencode
class GithubRequestHandler(webapp2.RequestHandler):
def get(self):
# this handler need to be bind to redirect_url
# get authentication code
github_code = self.request.get('code')
# prepare data to exchange access token
github_token_url = "https://github.com/login/oauth/access_token"
github_token_parameters = {
'client_id': 'Your Github client id',
'client_secret': 'Your Github client secret',
'code': github_code}
# exchange access token
data = urlfetch.fetch(github_token_url, payload=urlencode(github_token_parameter), method='POST')
# data will perform in the following form:
# access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&scope=user%2Cgist&token_type=bearer
# extract access_token from the string
# save the access_token to user's model
P.S.
the code is kinda of simulation of your application flow, it needs some tuning to be able to run on production :)
You try to create a webapp2 request handler, but it cannot be done this way. get_auth_token is not a WSGI webapp2 handler instance.
If you do not change githubauth.py you have to change your main.py.
class AuthUser(webapp2.RequestHandler):
def get(self):
if not ACCESS_TOKEN:
self.redirect(to your GetAuthTokenHandler)
This will result in two redirects if you do not have an access token.
RequestHandler needs to be instantiated with a request and a response for things to work properly.
That said, instantiating one and calling methods on it from inside the handler-method of another is pretty weird.