title: .NET Core 3.1, Vue, Axios and [ValidateAntiForgeryToken]
body: <p>I've been playing with this all day and reading as much as I can and I've utterly failed to get this working.</p>
  
  <p>I've compared my implementation to the MS documentation and other answers around SO and none of the approaches seem to work.</p>
  
  <p>The root of the problem is the switch from an anonymous user and a logged in user.</p>
  
  <p>I've been following the MS advice <a href="https://docs.microsoft.com/en-us/aspnet/core/security/anti-request-forgery?view=aspnetcore-3.1#javascript-ajax-and-spas" rel="nofollow noreferrer">here</a>. And various answers <a href="https://github.com/aspnet/Mvc/issues/4953" rel="nofollow noreferrer">here</a> and <a href="https://stackoverflow.com/questions/53487586/validateantiforgerytoken-in-an-asp-net-core-react-spa-application">here</a></p>
  
  <p>For testing I have one contact form with an endpoint decorated with <code>[ValidateAntiForgeryToken]</code>.</p>
  
  <p>The flow is:</p>
  
  <p>Visit the site, post this form and everything works fine.
  Login
  Visit the form, post - BOOM - The provided antiforgery token was meant for a different claims-based user than the current user.</p>
  
  <p>In my <code>public void Configure(</code> method, I have:</p>
  
  <pre><code>app.Use(async (context, next) =&gt;
  {
          var tokens = antiforgery.GetAndStoreTokens(context);
          context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false });
  
      await next();
  });
  </code></pre>
  
  <p>In my <code>public void ConfigureServices(</code> method I have:</p>
  
  <pre><code>services.AddAntiforgery(options =&gt; options.HeaderName = "X-CSRF-TOKEN");
  </code></pre>
  
  <p>In my Vue Router I have added a call to a method on my axios API like this:</p>
  
  <pre><code>router.afterEach((to, from) =&gt; {
      api.readCsrfCookieAndSetHeader();
  });
  </code></pre>
  
  <p>This method just reads the cookie and updates the header:</p>
  
  <pre><code>public readCsrfCookieAndSetHeader() {
      console.info('READING CSRF-TOKEN');
      if (document.cookie.indexOf('CSRF-TOKEN') &gt; -1) {
          const v = document.cookie.match('(^|;) ?' + 'CSRF-TOKEN' + '=([^;]*)(;|$)');
          const r = v ? v[2] : '';
          // console.log(r);
          this.csrfToken = r;
          axios.defaults.headers.common['X-CSRF-TOKEN'] = this.csrfToken;
          console.log(axios.defaults.headers.common['X-CSRF-TOKEN']);
      } else {
          this.csrfToken = '';
      }
  }
  </code></pre>
  
  <p>I can see this value changing page by page.  One suggestion that seem to have worked for some is to rerun <code>GetAndStoreTokens</code> at the point where the user is signed in, such as:</p>
  
  <pre><code>var user = await _userManager.FindByEmailAsync(userName);
  var result = await _signInManager.PasswordSignInAsync(user, password, true, false);
  _httpContextAccessor.HttpContext.User = await _signInManager.CreateUserPrincipalAsync(user);
  if (result.Succeeded)
  {
      // get, store and send the anti forgery token
      AntiforgeryTokenSet tokens = _antiforgery.GetAndStoreTokens(_httpContextAccessor.HttpContext);
      _httpContextAccessor.HttpContext.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false });
  }
  
  return result;
  </code></pre>
  
  <p>But this hasn't worked for me either.</p>
  
  <p>I've also tried updating the value with an axios interceptor, like this:</p>
  
  <pre><code>axios.interceptors.response.use(
      (response) =&gt; {
          // this.readCsrfCookieAndSetHeader();
          return response;
      }, 
      (error) =&gt; {
  </code></pre>
  
  <p>But that's really just really another way in to get the value updated that I'm sure is already being updated.</p>
  
  <p>I've run out of ideas and, it seems, things to try. Hence this Q.</p>
  
  <p>Have I missed anything obvious? It seems like I've replicated the MS Angular example nearly verbatim so I'm at a loss as to what I've done wrong.</p>
  
  <p>Any pointers would be very much appreciated.</p>