Log out from Drupal 8 with rest

Viewed 1492

From this link looks like logout can be performed sending a post to

http://domain/user/logout?_format=json&token=logout_token

where logout_token is the value returned from a previous login (example below)

{
"current_user": {
    "uid": "65",
    "name": "FooBar"
},
"csrf_token": "WDwkGWulI1qBkwDuHtZX8Hakl4X2T7kKIm5kG5StWng",
"logout_token": "l_6TO3cYldLtOx870LI0cYNUwi0wPNSneUA4eZXcZQk"
}

Straightforward, but I'm stuck with a 403 error.

I set my rest User resource as the following:

/user/{user}: GET, PATCH, DELETE
/entity/user: POST  
methods: GET, POST
formats: json
authentication: basic_auth

My Drupal services.yml contains:

cors.config:
    enabled: true
    # Specify allowed headers, like 'x-allowed-header'.
    allowedHeaders: ['*']

    # Specify allowed request methods, specify ['*'] to allow all possible ones.
    allowedMethods: ['*']

    # Configure requests allowed from specific origins.
    allowedOrigins: ['*']

    # Sets the Access-Control-Expose-Headers header.
    exposedHeaders: false

    # Sets the Access-Control-Max-Age header.
    maxAge: false

    # Sets the Access-Control-Allow-Credentials header.
    supportsCredentials: false

Even though Drupal and the caller are on two different servers (be and fe are hosted on two physical different servers), there are no issues with the cors.

I tried two simple scripts (php and vue js - they do the same thing) and getting the same result

PHP

$url = 'domain/user/logout?_format=json&token=' . $token;

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, $url);        
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, 1);

curl_setopt($curl, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Access-Control-Allow-Credentials: true'
    ));

$output = curl_exec($curl);
$info = curl_getinfo($curl);

$response = [
    'info' => $info,
    'data' => json_decode($output, true)
];

curl_close($curl);

return $response;

Vue JS

import Axios from 'axios'

Vue.prototype.$http = Axios

var URL = 'domain/user/logout?_format=json&token=' + this.logout_token

this.$http.post(URL).then(response => {
  console.log(response)
})
.catch(error => {
    console.log(error)
})
.finally(() => {
    this.loading = false
})

I tried to fire the post request from postman and it worked but I noticed it creates a cookie.

Anyone solved/understood how it works?

3 Answers

I struggled mightily with log out. CORS was set correctly and the

endpoints: http://domain/user/logout?_format=json&token=logout_token

was set as mentioned above. The only thing I was missing is this one line:

withCredentials: true

which then got it working. We can now log in and out! I hope this is helpful to anyone else who is having issues with logout in a decoupled system.

You'll want to use the logout_token as the token Query string param. Do not confuse that token with the X-CSRF-Token that is usually applied to the Headers.

The message you're seeing that mentions 'csrf_token' is either a typo or just the default Parent Class's message and the core developers haven't gotten around to adjusting that REST Logout messaging yet.

None of the above solutions worked for me because we were using simple oAuth for Authentication.

2 things you should be doing:

  1. It should be a Get request and not a Post request.
  2. If you are using Simple OAuth for user authentication you won't need the logout token. Use the access token generated by Simple oAuth as an Authorization header.

Here is an example code:-

const drupalLogout = async () => {
  const oauthToken = JSON.parse(localStorage.getItem('drupal-oauth-token'));
  const logoutoken = oauthToken.access_token;
  if (logoutoken) {
    const res = await fetch(`${base_url}/user/logout?_format=json`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${logoutoken}`,
      },
    });
    if (res.ok) {
      return true;
    }
  }
};

I am using the access token stored in my browser localStorage when the user logs in.

Related