Why am I unable to sign out using devise_token_auth and curl?
Answering my own question, I wasn't returning certain sign_in response header values correctly with the sign_out request.
I found a related post which pointed out some of the critical headers. The trick is to capture the access-token, client, and uid header values from the sign_in response, then include them as parameters in the sign_out request:
curl -i -X DELETE http://localhost:3000/api/v1/auth/sign_out -F access-token="Ae1yaTYLkSAgdhz3LtPAZg" -F client="9AmYF6NS8tP6EOD5nPSuxw" -F uid="user@nowhere.org"
Here's an RSpec test to illustrate and verify:
require 'rails_helper'RSpec.describe "Authentication", type: :request do it "logs a user out" do user = User.create!( name: "Some Dude", email: "user@nowhere.org", password: "password", confirmed_at: Date.today ) # initial sign in to generate a token and response post api_v1_user_session_path, { email: user.email, password: user.password } expect(user.reload.tokens.count).to eq 1 # sign out request using header values from sign in response delete destroy_api_v1_user_session_path, { "access-token": response.header["access-token"], client: response.header["client"], uid: response.header["uid"] } response_body = JSON.load(response.body) expect(response_body["errors"]).to be_blank expect(response.status).to eq 200 # user token should be deleted following sign out expect(user.reload.tokens.count).to eq 0 endend
In details, do the following steps:
Step 1:
curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST http://localhost:3000/api/v1/auth/sign_in -d "{\"email\":\"user@example.com\",\"password\":\"password\"}"
You'll get a response like this:
* Trying ::1...* Connected to localhost (::1) port 3000 (#0)> POST /api/v1/auth/sign_in HTTP/1.1> Host: localhost:3000> User-Agent: curl/7.43.0> Content-Type: application/json> Accept: application/json> Content-Length: 50>* upload completely sent off: 50 out of 50 bytes< HTTP/1.1 200 OK< X-Frame-Options: SAMEORIGIN< X-Xss-Protection: 1; mode=block< X-Content-Type-Options: nosniff< Access-Token: BqXcWQi0-9faLyxP1LnUKw< Token-Type: Bearer< Client: dYSqVgM9VT6fV9Y5MFWpJQ< Expiry: 1465679853< Uid: user@example.com< Content-Type: application/json; charset=utf-8< Etag: W/"9ad6a23f014a744a7ec83b4e0e9d27aa"< Cache-Control: max-age=0, private, must-revalidate< X-Request-Id: 6566bd38-1ad7-491a-a1ab-e41458b9b704< X-Runtime: 0.184807< Server: WEBrick/1.3.1 (Ruby/2.3.0/2015-12-25)< Date: Sat, 28 May 2016 21:17:33 GMT< Content-Length: 135< Connection: Keep-Alive<* Connection #0 to host localhost left intact{"data":{"id":6,"provider":"email","uid":"user@example.com","name":"testuser","nickname":null,"image":null,"email":"user@example.com"}}%
Step 2:
Now, you want to sign the user out.
curl -i -X DELETE http://localhost:3000/api/v1/auth/sign_out -F access-token="BqXcWQi0-9faLyxP1LnUKw" -F client="dYSqVgM9VT6fV9Y5MFWpJQ" -F uid="user@example.com"
You'll get a response like this:
HTTP/1.1 200 OKX-Frame-Options: SAMEORIGINX-Xss-Protection: 1; mode=blockX-Content-Type-Options: nosniffContent-Type: application/json; charset=utf-8Etag: W/"7363e85fe9edee6f053a4b319588c086"Cache-Control: max-age=0, private, must-revalidateX-Request-Id: 8f7a297a-6a72-4c9d-a210-48c29fb4bfe0X-Runtime: 0.095060Server: WEBrick/1.3.1 (Ruby/2.3.0/2015-12-25)Date: Sat, 28 May 2016 21:19:18 GMTContent-Length: 16Connection: Keep-Alive{"success":true}%
In step 2, I've added the access-token and client as per the response that we received in step 1 (Access-Token: BqXcWQi0-9faLyxP1LnUKw and Client: dYSqVgM9VT6fV9Y5MFWpJQ).
That's it! :)
I took the help of @user3006381's answer! All credits to him.