csrf – What should I worry about when attaching a token to a request manually?

I’m developing a platform that has 2 parts:

  1. An API written using Laravel, that integrates with the database and provided data in a restful state.
  2. Multiple fronts that connect to the API and perform different tasks.

Laravel suggests that you should use their built-in cookie-based sessions to implement your app, but for 2 reasons I have decided to not use it:

  1. It’s not stateless
  2. I need to connect multiple fronts ( JS, Vue, Mobile ) to the API, so the logic needs to be reusable

What I’m trying to do is to use the Authorization header to authorize a user. Here are the steps:

  1. A user logs into the system using the build-in Laravel sessions

  2. A token is generated and as suggested per their docs, the plain unencrypted value is passed to the user. The encrypted value is stored in database.

  3. The token is stored in a cookie on user’s device, using php’s setcookie(); function.

  4. On each request, the token is attached to the request’s header, via front. For example in a jQuery/JS ajax request:

    xhr.setRequestHeader( "Authorization", "Bearer " + decodeURIComponent( getTokenCookieValue() ) );
    
  5. Laravel then automatically verifies if this header is set and validates its value.

I need to mention that tokens can not be manually generated. Each time a session expires, the token that was generated after that session will expire too. So, they have the same lifetime as the session, but they’re not aware of the session’s state. The tokens are updated via a defined Job.

Now my question is, is this even safe? What’s there to worry about here? If it’s not safe, what would be a safe way to store and send this token on each request?

I’m also wondering about CSRF attacks. As far as I understand, it happens when a browser requests a page and because the cookies are automatically attached, your app will be vulnerable. But in this case, it is manually retrieved, and the normal cookie value sent by browser is NOT evaluated. So to me it seems like it’s not possible to forge a CSRF attack unless malicious code is injected to the user’s page. Would that be correct, and should I add CSRF protection too?