4

I'm passing to the server in the POST request body the Token of the user. I need to find out which user this token belongs to. In laravel/sanctum documentation I found out that it is possible to do it only by putting the Token as "Authorization": "Bearer ****" header. But it is not my case, I need to pass it in the POST body. Is there a way to do so?

Dmytro Huz
  • 1,514
  • 2
  • 14
  • 22

4 Answers4

5

If you want to verify that a token is valid and get the corresponding user, there is a builtin method in the Sanctum library that allows you to do exactly that:

// Fetch the associated token Model
$token = \Laravel\Sanctum\PersonalAccessToken::findToken($yourToken);

// Get the assigned user
$user = $token->tokenable;

Karim Geiger
  • 622
  • 1
  • 8
  • 17
  • But add this $hashedToken = $request->bearerToken(); before the code to get the hashed token in an elegant way. – Alex Nov 01 '22 at 15:06
3

I found a solution by making a few experiments and reading the source code of Sanctum. User's data is possible to get by token in POST data in that way:

$post_data = $request->all();
if (isset($post_data['user_token'])) {
    [$id, $user_token] = explode('|', $post_data['user_token'], 2);
    $token_data = DB::table('personal_access_tokens')->where('token', hash('sha256', $user_token))->first();
    $user_id = $token_data->tokenable_id; // !!!THIS ID WE CAN USE TO GET DATA OF YOUR USER!!!
}
Dmytro Huz
  • 1,514
  • 2
  • 14
  • 22
0

i have done the following:

my LoginController

class LoginController extends Controller
{
    use ApiResponser;

    public function __invoke(Request $request)
    {
        // attempting login
        if(!auth()->attempt($request->only('email', 'password'))) {
            return $this->error(401, 'Credentials not match' );
        }

        // Delete old tokens
        auth()->user()->tokens()->delete();

        // Succesfull login and new token created.
        return $this->success([
            'token' => auth()->user()->createToken('API Token', auth()->user()->abilities())->plainTextToken
        ]);
    }

So you have clear insight what i do next in my ApiResponser is is only for pretty status messages.

namespace App\Traits;


use Illuminate\Http\JsonResponse;

trait ApiResponser
{
    /**
     * Returns a succesfull response
     * @param $data
     * @param string|null $message
     * @param int $code
     * @return JsonResponse
     */
    protected function success($data, string $message = null, int $code = 200): JsonResponse
    {
        return response()->json([
            'status' => 'Success',
            'message' => $message,
            'data' => $data
        ], $code);
    }

    /**
     * Return an error JSON response.
     *
     * @param  string  $message
     * @param  int  $code
     * @param  array|string|null  $data
     * @return JsonResponse
     */
    protected function error( int $code, string $message = null, $data = null): JsonResponse
    {
        return response()->json([
            'status' => 'Error',
            'message' => $message,
            'data' => $data
        ], $code);
    }

}

I receive the following json

{
    "status": "Success",
    "message": null,
    "data": {
        "token": "156|mmEL7OV24DO79W5E6IdAXiQaHa8BCXK6271hLE3m"
    }
}

I have a nuxtJS project and in my login component i have the following

  methods: {
    login(e) {
      e.preventDefault()
      this.$auth
        .loginWith('laravelSanctum', {
          data: this.form,
        })
        .then((resp) => {
          this.$auth.strategy.token.set(resp.data.data.token)
          this.$axios.setToken(resp.data.data.token, 'Bearer')
        })
        .catch((e) => {
          // eslint-disable-next-line no-console
          console.log('Failed Logging In')
        })
    },
  },

And finally in my user store in VueX

export const actions = {
  async fetchAllUsers(state, payload = false) {
    state.commit('SET_BUSY', true)
    this.$axios.setToken(this.$auth.strategy.token.get(), 'Bearer')
    const response = await this.$axios('users', {
      headers,
      params: payload,
    })
    console.log(response.data)
    state.commit('GET_USERS', response.data.data.data)
    state.commit('SET_SEARCH', response.data.data.search)
    state.commit('SET_FILTERS', response.data.data.filters)
    state.commit('SET_BUSY', false)
  },
  async createUser(state, payload) {
    this.$axios.setToken(this.$auth.strategy.token.get(), 'Bearer')
    const response = await this.$axios.post('user', payload, {
      headers,
    })
    state.commit('ADD_USER', response.data.data)
    return response
  },
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Marcel Santing
  • 103
  • 1
  • 5
0
  if($request->has('token')){

         [$id, $token] = explode('|', $request->input('token'), 2);
         $token_data = DB::table('personal_access_tokens')->where('token', hash('sha256', $token))->first();
         
         dd($token_data);
  }