8

I am using Actions on Google (on mobile phone Google Assistant) and by using its Account Linking I am logged in Auth0(log-in window: image).

However, I want to log out from Auth0 whenever I want so that I can test the whole procedure from the beginning.

I wrote the following source code in Python and Flask following the Auth0 docs (https://auth0.com/docs/logout).

from flask import Flask, render_template, request, jsonify
import requests

app = Flask(__name__)
@app.route("/", methods=['GET', 'POST'])
def index():

    session['user'] = 'Poete_Maudit'

    data = request.get_json()

    if data is not None:
        action = data["queryResult"]["action"]
    else:
        return 'HERE'

    # Triggers actions.intent.SIGN_IN which leads to Auth0
    if (action == 'sign'):

        return jsonify({"payload": {
                    "google": {
                        "expectUserResponse": True,
                        "isSsml": False,
                        "noInputPrompts": [],
                        "systemIntent": {
                            "data": {
                                "@type": "type.googleapis.com/google.actions.v2.SignInValueSpec"
                            },
                            "intent": "actions.intent.SIGN_IN"
                        }
                      }
                     }
                    })
    # I have other if statements below which retrieve the access token 
    # and do in general other stuff on Actions on Google app
    # but it is too long to include it here

@app.route('/logout')
def logout():
    session.clear()
    return redirect('https://project_id.eu.auth0.com/v2/logout?returnTo=http://127.0.0.1:5000')

if __name__== "__main__":
    app.secret_key = os.urandom(24)
    app.run(debug=True)

After I have executed the whole log-in procedure one time then I manually go (from the browser) to http://127.0.0.1:5000/logout which successfully redirects me to http://127.0.0.1:5000. At the python console I am getting:

127.0.0.1 - - [06/Jun/2018 14:09:04] "GET /logout HTTP/1.1" 302 -
127.0.0.1 - - [12/Jun/2018 11:03:16] "GET / HTTP/1.1" 200 -

and at the Auth0 logs section I am getting Success Logout (image).

However, again when I am restarting the whole process on the mobile phone Google Assistant the log-in window does not appear and I am again already logged in Auth0 with the same accessToken.

How can I properly log out by clearing the session and/or the cookies on http://127.0.0.1:5000 and hence make the Auth0 log-in window to appear again?

P.S.

1) Keep in mind please that for now I am doing all this with Python and ngrok. If I restart the ngrok session then the log-in window re-appears but obviously I want to do this programmatically.

2) Do not take anything for granted please. I may be missing something very elementary in what I am doing so please feel free to ask me even very elementary questions about this.

Outcast
  • 4,967
  • 5
  • 44
  • 99

2 Answers2

4

I have sent a message about it to Google Support and I got the following answer:

To unlink your account you can use this link (https://gala-demo.appspot.com), in the field Service ID enter the project ID and add "_dev" at the end (in your case it will be "Dnipro-Chatbot_dev"), then click Unlink My Accounts.

Moreover, I asked them if I can do this programmatically (than only manually as above) and I got the following answer:

I'm not sure if this is possible to do in Python, but you can try following: If you can send back a 401 status code from your oauth token exchange endpoint. The 401 will tell AoG that the access token is invalid and force AoG to initiate the account linking flow again. Hope this can help you.

In conclusion, you can certainly use the link above to unlink the account as I tested it and it works fine. Regarding the second answer, I am not sure that this is exactly possible at least in the way it is stated. You cannot really send programmatically a 401 status code from Auth0. What you can do on Auth0 is to set the expiration time of the JWT of your Auth0 app very low (e.g. 60 seconds) and in this way force the access token to be revoked. But this is not again really a programmatic solution and I have not tested it yet.

Outcast
  • 4,967
  • 5
  • 44
  • 99
2

The /v2/logout endpoint in Auth0 is meant to be used from the front-channel (i.e. the browser), so your backend application should return a 302 redirect response pointing to the /v2/logout endpoint (you can use the returnTo parameter as explained in the docs if you want to redirect the user back to a specific URL after clearing the session).

By making a back channel request as you are doing now (server-to-server) the session cookie is missing so Auth0 does not know which session to terminate.

Note also that the /v2/logout endpoint clears the session in Auth0, but you will also have to clear the session in your application as well. If using Flask, take a look at these Flask session.clear examples.

Nico Sabena
  • 6,764
  • 1
  • 14
  • 11
  • Thank for your answer(upvote). I am not completely aware of the technical details that you are mentioning here so your answer is a bit dense for me. For example: 1) What should the url and the parameters of my HTTP request be?, 2) Is the Flask.session clear necessary? I do not want to re-direct the user anywhere but simply to log out the user at dead time (when the user is not using my Python app) so that the user can log in anew again when she/he is using my app again from the beginning (for testing purposes). – Outcast May 30 '18 at 16:31
  • As I said, the `/v2/logout` is meant to be requested from the browser. This is so that the browser sends the session cookie, and Auth0 can identify who is requesting the logout and clear the session. The way to do this is returning a redirect response from the server, which instructs the browser to do a new request to the new location (i.e. the `/v2/logout` endpoint). Since you don't want the user to just endup in a blank "OK" page, you use the `returnTo` parameter to redirect the user back to a different place (like the home page of your app). – Nico Sabena May 30 '18 at 16:36
  • As for the sessions, as the [logout docs](https://auth0.com/docs/logout) explain, there are three session that you need to keep in mind: - The session at your application (we can't clear that, you manage it). - The session at Auth0 (you clear it by redirecting the user to /v2/logout) - The session at the upstream identity provider (like Google). You *can* clear it using the `federated` parameter, but it's usually not recommended (most users don't appreciate a foreign application clearing a session). – Nico Sabena May 30 '18 at 16:39
  • If you just clear the session at Auth0, your application still "knows" who the user is and so it might skip requesting a new token when you ask for it. But that's a little out of the realm of the identity provider (Auth0) and more related to the overall architecture of your application. – Nico Sabena May 30 '18 at 16:41
  • Thanks again for you detailed comments. Yes, I now understand even better that my app will remember because of the session cookie. However, to be precise, I have also sent a GET request to the `/v2/logout?federated` and nothing changed (perhaps I am missing something here). Therefore, for concluding, do I have to do anything by sending a http request to `Auth0` or only I have to do something (clearing etc) with my session on `Flask` for making the log-in window to appear again? – Outcast May 30 '18 at 16:48
  • You need to clear your session in Flask, that's for sure. And you need to use the `/v2/logout` endpoint if you want to clear the session in Auth0, so that the next time that the app requests a token to Auth0, Auth0 will ask the user to authenticate again. But your server should not make a GET request to `/v2/logout`. It's the user-agent (i.e. the browser) that needs to make that request, so your app merely returns a redirect result to the `/v2/logout` endpoint. This seems to be what you need: http://flask.pocoo.org/docs/1.0/quickstart/#redirects-and-errors – Nico Sabena May 30 '18 at 19:29
  • 1
    @app.route('/logout') def logout(): session.clear() return redirect('https://yourtenant.auth0.com/v2/logout?returnTo=' + url_for('/')) – Nico Sabena May 30 '18 at 19:30