0

I have set up an API using configured with auth protected endpoints as described in this excellent tutorial

https://blog.miguelgrinberg.com/post/restful-authentication-with-flask

My end user, however, wants to authenticate by passing a JSON and then remain authenticated until the session expires.

The current method of authentication uses headers, as in the tutorial

$ curl -u miguel:python -i -X GET http://127.0.0.1:5000/api/resource
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 30
Server: Werkzeug/0.9.4 Python/2.7.3
Date: Thu, 28 Nov 2013 20:02:25 GMT

{
  "data": "Hello, miguel!"
}

The users want to send the following instead

curl -L -X POST 'https://api.org/auth/?json={"client_id":"CLIENT ID","client_secret":"CLIENT SECRET","grant_type":"password"}' -H 'Content-Type: application/json'

There is clearly a way to authenticate once and remain authenticated because flask-restx endpoints display the attached image when you try to use an @auth.login_required decorated endpoint. Does anyone know what code this manual login code triggers and whether I can replicate the process by passing data received into an endpoint via JSON?

I have considered an internal redirect or curl-request but this seems unnecessarily clunky

manual login via API

1 Answers1

0

The username/password prompt in your image is implemented by web browsers when the server uses the Basic Authentication method. If your client is not a web browser, then there is no user interface to request username and password, you have to implement that yourself.

Your assertion that "there is clearly a way" to authenticate and remain authenticated for the duration of the session is incorrect. The HTTP protocol is stateless, which means that every request stands on its own. You think that session authentication is possible because in some situations the data that you as a client are not providing is automatically inserted by the web browser or HTTP client. Examples:

  • When you log in to a website and then the website remembers who you are as you navigate from page to page, the browser is inserting a session cookie into all the requests that the client sends. The server writes information about the client in the session, so that it can recover it every time a request from the client is received.

  • When you use the username/password Basic Authentication solution that you referenced in your question, the browser saves the username and password that you entered, and inserts an Authorization header with them into all successive requests sent during the session. From the side of the server, every request comes with a username and a password and needs to be verified from scratch.

Finally, the JSON example that you show appears to be based on the OAuth protocol. This is a fairly extensive solution with many different flows. The one that you use in your example is the Password grant, in which the client passes username and password and receives an access token in exchange. This access token must be provided in all successive requests you make.

If your client application runs in the browser, then the two options that you have for the browser to help out with the authentication are:

  • Use session cookies. With Flask, this can be done with the Flask-Login extension.
  • Use Basic Authentication, to let the browser prompt the user for credentials, which are then automatically sent in successive requests. This is fully supported by the Flask-HTTPAuth.
Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • Makes sense. May be I'm misunderstanding what they are looking for. You are correct that I am generating an auth toiken. I will advise them that it will need to be provided in all subsequent requests. Thanks for the information. Think that I have actually completed what I needed to create in this case. – Peter J. Freeman Oct 11 '22 at 13:19