Forbidden (403) - CSRF verification failed. Request aborted

Hi developers,

It seems that the API server is blocking the POST / PUT requests because of the Django CSRF (Cross Site Request Forgery) protection. Here is a sample response of PUT request to /v1/me/settings/.

<!DOCTYPE html>
<html lang="en">
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta name="robots" content="NONE,NOARCHIVE">
  <title>403 Forbidden</title>
  <style type="text/css">
    html * { padding:0; margin:0; }
    body * { padding:10px 20px; }
    body * * { padding:0; }
    body { font:small sans-serif; background:#eee; }
    body>div { border-bottom:1px solid #ddd; }
    h1 { font-weight:normal; margin-bottom:.4em; }
    h1 span { font-size:60%; color:#666; font-weight:normal; }
    #info { background:#f6f6f6; }
    #info ul { margin: 0.5em 4em; }
    #info p, #summary p { padding-top:10px; }
    #summary { background: #ffc; }
    #explanation { background:#eee; border-bottom: 0px none; }
<div id="summary">
  <h1>Forbidden <span>(403)</span></h1>
  <p>CSRF verification failed. Request aborted.</p>


<div id="explanation">
  <p><small>More information is available with DEBUG=True.</small></p>



Not an OGS dev, but if I was, I’d ask for a bit more info. How are you executing this request? Describe the scenario. Browser button on your own UI page that’s trying to use the OGS login cookie? Python/Perl/Ruby script? Maybe send the actual raw HTTP request instead of just the HTML returned, and a code snippet? (Obviously, redact any sensitive info such as API key.)

Thanks @pbgarden.

I was using the /v1/me/settings/ api.

It could be reproduced by

curl --include \
     --request PUT \
     --header "Authorization: Bearer ${TOKEN}" \
     --header "Content-Type: application/json" \
     --data-binary "{\"profile\": {\"first_name\": \"Ted\", \"last_name\": \"Robbins\"}}" \

How are you generating your token? It seems like it may just be falling into some csrf logic whenever it’s forbidden.

I was following this guide@apiary.

I used

  1. client_id
  2. client_secret
  3. bot_username
  4. bot_app_password

and get the token from

It is fine to use the token in GET request but not POST or PUT, etc.