wagnerdelima / drf-social-oauth2

drf-social-oauth2 makes it easy to integrate Django social authentication with major OAuth2 providers, i.e., Facebook, Twitter, Google, etc.
https://drf-social-oauth2.readthedocs.io/en/latest/
MIT License
271 stars 34 forks source link

BadHeaderError("Header values can't contain newlines (got %r)" % value) #131

Closed Nizzy94 closed 1 year ago

Nizzy94 commented 2 years ago

Describe the bug I got access_token from google which I'm supposed to use to authenticate users. Everything works fine when the user is authenticating for the first time. But when the user logs out and tries to login again, it gives this wired error.

This never happened when I was using the old gapi for login. I am currently using the new recommended GSI google provided.

To Reproduce Steps to reproduce the behavior: I have created a Demo Repo for this. Clone it and run pip install -r requirements.txt and you're good to go NB: Don't forget to create a virtual env before installation.

  1. Go to Google playground to get an access token
  2. Send the details to /auth/convert-token endpoint and make sure the user is registered in the database.
  3. Try sending the same credentials to the same endpoint. NB: it doesn't matter whether it's a new access_token. as long as it belongs to the same user, the error will be the response.

Expected behavior A response with JSON data of tokens generated by the backend

Screenshots

Screenshot 2022-06-11 at 9 11 23 PM

Additional context I used to work with the Old gapi.$Auth system.

The issue appears to be coming from ConvertTokenView class in site-packages/drf_social_oauth2.py. When a user registers for the first time, these are the headers:

dict_items([('Content-Type', 'application/json'), ('Cache-Control', 'no-store'), ('Pragma', 'no-cache')])

when the same user tries to access convert-token endpoint, a PS1 header is added(which contains the badHeader) together with other headers. Below is the full list of headers:

dict_items([
('USER', 'nizzy'), 
('__CFBundleIdentifier', 'com.microsoft.VSCode'), 
('COMMAND_MODE', 'unix2003'), 
('LOGNAME', 'nizzy'), 
('PATH', '/Users/nizzy/Documents/django_projects/unicart_django/unicart_market/venv/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/Library/Frameworks/Python.framework/Versions/3.9/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/MacGPG2/bin:/Library/Apple/usr/bin:/Applications/Postgres.app/Contents/Versions/latest/bin:/Users/nizzy/Documents/django_projects/unicart_django/unicart_market/venv/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/Library/Frameworks/Python.framework/Versions/3.9/bin:/Users/nizzy/dev/flutter/bin:/Users/nizzy/.npm-global/bin:/Users/nizzy/dev/flutter/bin:/Users/nizzy/.npm-global/bin'),
('SSH_AUTH_SOCK', '/private/tmp/com.apple.launchd.9ZW0MlkXPb/Listeners'), 
('SHELL', '/bin/zsh'), ('HOME', '/Users/nizzy'), ('__CF_USER_TEXT_ENCODING', '0x1F5:0x0:0x0'), 
('TMPDIR', '/var/folders/t1/97b4p4_116l5yvb9lws3qtj40000gn/T/'), 
('XPC_SERVICE_NAME', '0'), 
('XPC_FLAGS', '0x0'), 
('ORIGINAL_XDG_CURRENT_DESKTOP', 'undefined'), 
('PWD', '/Users/nizzy/Documents/django_projects/unicart_django/unicart_market'), ('APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL', 'true'), 
('MANPATH', '/opt/homebrew/share/man:/usr/share/man:/usr/local/share/man:/usr/local/MacGPG2/share/man:/opt/homebrew/share/man:'), ('INFOPATH', '/opt/homebrew/share/info:/opt/homebrew/share/info:'), ('HOMEBREW_PREFIX', '/opt/homebrew'), 
('LC_CTYPE', 'UTF-8'), ('TERM', 'xterm-256color'), ('GPG_TTY', 'not a tty'), ('ZSH', '/Users/nizzy/.oh-my-zsh'), ('TERM_SESSION_ID', 'DD29542B-0253-4567-B80E-31F4499A024B'), ('P9K_SSH', '0'), ('HOMEBREW_CELLAR', '/opt/homebrew/Cellar'), ('SHLVL', '3'), ('HOMEBREW_REPOSITORY', '/opt/homebrew'), ('TERM_PROGRAM_VERSION', '1.67.2'), ('PAGER', 'less'), ('_P9K_TTY', '/dev/ttys000'), ('LESS', '-R'), ('LSCOLORS', 'Gxfxcxdxbxegedabagacad'), ('TERM_PROGRAM', 'vscode'), ('P9K_TTY', 'old'), ('LANG', 'en_GB.UTF-8'), ('COLORTERM', 'truecolor'), ('VSCODE_GIT_IPC_HANDLE', '/var/folders/t1/97b4p4_116l5yvb9lws3qtj40000gn/T/vscode-git-d7ee048a49.sock'), ('VSCODE_GIT_ASKPASS_NODE', '/Applications/Visual Studio Code.app/Contents/MacOS/Electron'), ('VSCODE_GIT_ASKPASS_EXTRA_ARGS', '--ms-enable-electron-run-as-node'), ('VSCODE_GIT_ASKPASS_MAIN', '/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass-main.js'), ('GIT_ASKPASS', '/Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass.sh'), ('OLDPWD', '/Users/nizzy/Documents/django_projects/unicart_django/unicart_market'), 

('PS1', '(venv) ${$((_p9k_on_expand()))+}%{${_p9k__raw_msg-}${_p9k__raw_msg::=}%}${(e)_p9k_t[7]}${_p9k__1-${${:-${_p9k__d::=0}${_p9k__rprompt::=${_p9k__1r-${${:-${_p9k__bg::=NONE}${_p9k__i::=0}${_p9k__sss::=}}+}${${:-${P9K_CONTENT::=}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=8}}${_p9k__n:=${${(M)${:-x$_p9k__bg}:#x(|0)}:+10}}${_p9k__n:=11}${_p9k__c::="${P9K_CONTENT}"}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1r:+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}0}}}+}${${_p9k__e:#00}:+${_p9k_t[$_p9k__n]/<_p9k__w>/$_p9k__w}${_p9k__c}%b%k%f${${:-${_p9k__w::=%b%k%f}${_p9k__sss::=%b%k%f}${_p9k__i::=1}${_p9k__bg::=}}+}}${${:-"${${(%):-%j}:#0}"}:+${${:-${P9K_CONTENT::=""}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=12}}${_p9k__n:=${${(M)${:-x$_p9k__bg}:#x(|0)}:+14}}${_p9k__n:=15}${_p9k__v::=\uf013}${_p9k__c::="${P9K_CONTENT}"}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1rbackground_jobs+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}1}}}+}${${_p9k__e:#00}:+${_p9k_t[$_p9k__n]/<_p9k__w>/$_p9k__w}${_p9k__v}${${(M)_p9k__e:#11}:+ }${_p9k__c}%b%k%F{070\\}${${:-${_p9k__w::=%b%k%F{070\\}}${_p9k__sss::=%b%k%F{070\\}}${_p9k__i::=3}${_p9k__bg::=}}+}}}${${:-"${(M)${#P9K_PYENV_PYTHON_VERSION}:#0}"}:+${${:-${P9K_CONTENT::=unicart_market}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=92}}${_p9k__n:=${${(M)${:-x$_p9k__bg}:#x(|0)}:+94}}${_p9k__n:=95}${_p9k__v::=\ue73c}${_p9k__c::="${P9K_CONTENT}"}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1rvirtualenv+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}1}}}+}${${_p9k__e:#00}:+${_p9k_t[$_p9k__n]/<_p9k__w>/$_p9k__w}${_p9k__v}${${(M)_p9k__e:#11}:+ }${_p9k__c}%b%k%F{037\\}${${:-${_p9k__w::=%b%k%F{037\\}}${_p9k__sss::=%b%k%F{037\\}}${_p9k__i::=6}${_p9k__bg::=}}+}}}${${:-"${${(%):-%#}:#\\#}"}:+${${:-${P9K_CONTENT::=%n@%m}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=16}}${_p9k__n:=${${(M)${:-x$_p9k__bg}:#x(|0)}:+18}}${_p9k__n:=19}${_p9k__c::=}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1rcontext+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}0}}}+}${${_p9k__e:#00}:+${_p9k_t[$_p9k__n]/<_p9k__w>/$_p9k__w}${_p9k__c}%b%k%F{180\\}${${:-${_p9k__w::=%b%k%F{180\\}}${_p9k__sss::=%b%k%F{180\\}}${_p9k__i::=31}${_p9k__bg::=}}+}}}${${:-"${${(%):-%#}:#\\%}"}:+${${:-${P9K_CONTENT::=%B%n@%m}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=20}}${_p9k__n:=${${(M)${:-x$_p9k__bg}:#x(|0)}:+22}}${_p9k__n:=23}${_p9k__c::="${P9K_CONTENT}"}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1rcontext+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}0}}}+}${${_p9k__e:#00}:+${_p9k_t[$_p9k__n]/<_p9k__w>/$_p9k__w}${_p9k__c}%b%k%F{178\\}${${:-${_p9k__w::=%b%k%F{178\\}}${_p9k__sss::=%b%k%F{178\\}}${_p9k__i::=31}${_p9k__bg::=}}+}}}${${:-${P9K_CONTENT::=12:18:27}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=24}}${_p9k__n:=${${(M)${:-x$_p9k__bg}:#x(|0)}:+26}}${_p9k__n:=27}${_p9k__c::="${P9K_CONTENT}"}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1rtime+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}0}}}+}${${_p9k__e:#00}:+${_p9k_t[$_p9k__n]/<_p9k__w>/$_p9k__w}${_p9k__c}%b%k%F{066\\}${${:-${_p9k__w::=%b%k%F{066\\}}${_p9k__sss::=%b%k%F{066\\}}${_p9k__i::=42}${_p9k__bg::=}}+}}$_p9k__sss%b%k%f}}${_p9k__lprompt::=${_p9k__1l-${${:-${_p9k__bg::=NONE}${_p9k__i::=0}${_p9k__sss::=%f}}+}${${:-${P9K_CONTENT::="%{d%}${:-"%B%F{039}"}${(Q)${:-"\\\\~"}}${:-"%b%k%F{031}"}/${${${_p9k__d:#-*}:+Documents}:-${:-"%F{103}"}Doc${:-"%b%k%F{031}"}${$((_p9k__d+=6))+}}/${${${_p9k__d:#-*}:+django_projects}:-${:-"%F{103}"}d${:-"%b%k%F{031}"}${$((_p9k__d+=14))+}}/${:-"%B%F{039}"}unicart_django${:-"%b%k%F{031}"}/${:-"%B%F{039}"}unicart_market${:-"%b%k%F{031}"}%{d%}"}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=28}}${_p9k__n:=${${(M)${:-x}:#x($_p9k__bg|${_p9k__bg:-0})}:+30}}${_p9k__n:=31}${_p9k__c::="${P9K_CONTENT}"}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1ldir+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}0}}}+}${${_p9k__e:#00}:+${${_p9k_t[$_p9k__n]/<_p9k__ss>/$_p9k__ss}/<_p9k__s>/$_p9k__s}${_p9k__c}%b%k%F{031\\}${${:-${_p9k__s::=%F{\\}}${_p9k__ss::= }${_p9k__sss::=%F{\\}}${_p9k__i::=1}${_p9k__bg::=}}+}}${(e)_p9k__vcs}${${:-"${${:-$_p9k__keymap.$_p9k__zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*overwrite*)}"}:+${${:-${P9K_CONTENT::=❯}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=32}}${_p9k__n:=${${(M)${:-x}:#x($_p9k__bg|${_p9k__bg:-0})}:+34}}${_p9k__n:=35}${_p9k__c::="❯"}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1lprompt_char+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}0}}}+}${${_p9k__e:#00}:+${${_p9k_t[$_p9k__n]/<_p9k__ss>/$_p9k__ss}/<_p9k__s>/$_p9k__s}${_p9k__c}%b%k%F{076\\}${${:-${_p9k__s::=%F{\\}}${_p9k__ss::= }${_p9k__sss::=%F{\\}}${_p9k__i::=3}${_p9k__bg::=}}+}}}${${:-"${${:-$_p9k__keymap.$_p9k__zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*insert*)}"}:+${${:-${P9K_CONTENT::=▶}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=36}}${_p9k__n:=${${(M)${:-x}:#x($_p9k__bg|${_p9k__bg:-0})}:+38}}${_p9k__n:=39}${_p9k__c::="▶"}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1lprompt_char+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}0}}}+}${${_p9k__e:#00}:+${${_p9k_t[$_p9k__n]/<_p9k__ss>/$_p9k__ss}/<_p9k__s>/$_p9k__s}${_p9k__c}%b%k%F{076\\}${${:-${_p9k__s::=%F{\\}}${_p9k__ss::= }${_p9k__sss::=%F{\\}}${_p9k__i::=3}${_p9k__bg::=}}+}}}${${:-"${(M)${:-$_p9k__keymap$_p9k__region_active}:#vicmd0}"}:+${${:-${P9K_CONTENT::=❮}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=40}}${_p9k__n:=${${(M)${:-x}:#x($_p9k__bg|${_p9k__bg:-0})}:+42}}${_p9k__n:=43}${_p9k__c::="❮"}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1lprompt_char+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}0}}}+}${${_p9k__e:#00}:+${${_p9k_t[$_p9k__n]/<_p9k__ss>/$_p9k__ss}/<_p9k__s>/$_p9k__s}${_p9k__c}%b%k%F{076\\}${${:-${_p9k__s::=%F{\\}}${_p9k__ss::= }${_p9k__sss::=%F{\\}}${_p9k__i::=3}${_p9k__bg::=}}+}}}${${:-"${(M)${:-$_p9k__keymap$_p9k__region_active}:#(vicmd1|vivis?|vivli?)}"}:+${${:-${P9K_CONTENT::=Ⅴ}${_p9k__n::=}${${${_p9k__bg:-0}:#NONE}:-${_p9k__n::=44}}${_p9k__n:=${${(M)${:-x}:#x($_p9k__bg|${_p9k__bg:-0})}:+46}}${_p9k__n:=47}${_p9k__c::="V"}${_p9k__c::=${_p9k__c//\r}}${_p9k__e::=${${_p9k__1lprompt_char+00}:-${${(%):-$_p9k__c%1(l.1.0)}[-1]}0}}}+}${${_p9k__e:#00}:+${${_p9k_t[$_p9k__n]/<_p9k__ss>/$_p9k__ss}/<_p9k__s>/$_p9k__s}${_p9k__c}%b%k%F{076\\}${${:-${_p9k__s::=%F{\\}}${_p9k__ss::= }${_p9k__sss::=%F{\\}}${_p9k__i::=3}${_p9k__bg::=}}+}}}%b%k$_p9k__sss%b%k%f${:-" %b%k%f"}}}}+}${(e)_p9k_t[6]}${${_p9k__h::=40.}+}${${_p9k__d::=$((_p9k__m-_p9k__h))}+}${_p9k__lprompt/\\%\\{d\\%\\}*\\%\\{d\\%\\}/${_p9k__1ldir-${:-"%B%F{039}"}${(Q)${:-"\\\\~"}}${:-"%b%k%F{031}"}/${${${_p9k__d:#-*}:+Documents}:-${:-"%F{103}"}Doc${:-"%b%k%F{031}"}${$((_p9k__d+=6))+}}/${${${_p9k__d:#-*}:+django_projects}:-${:-"%F{103}"}d${:-"%b%k%F{031}"}${$((_p9k__d+=14))+}}/${:-"%B%F{039}"}unicart_django${:-"%b%k%F{031}"}/${:-"%B%F{039}"}unicart_market${:-"%b%k%F{031}"}}}${${_p9k__m::=$((_p9k__d+_p9k__h))}+}}${${COLUMNS::=$_p9k__clm}+}'), 

('VIRTUAL_ENV', '/Users/nizzy/Documents/django_projects/unicart_django/unicart_market/venv'), 
('_', '/Users/nizzy/Documents/django_projects/unicart_django/unicart_market/venv/bin/python3'), ('DJANGO_SETTINGS_MODULE', 'core.settings'), ('TZ', 'UTC'), ('RUN_MAIN', 'true'), ('SERVER_NAME', '1.0.0.127.in-addr.arpa'), ('GATEWAY_INTERFACE', 'CGI/1.1'), ('SERVER_PORT', '8000'), ('REMOTE_HOST', ''), ('CONTENT_LENGTH', '466'), ('SCRIPT_NAME', ''), ('SERVER_PROTOCOL', 'HTTP/1.1'), ('SERVER_SOFTWARE', 'WSGIServer/0.2'), ('REQUEST_METHOD', 'POST'), ('PATH_INFO', '/auth/convert-token/'), ('QUERY_STRING', ''), ('REMOTE_ADDR', '127.0.0.1'), ('CONTENT_TYPE', 'application/json'), ('HTTP_USER_AGENT', 'Thunder Client (https://www.thunderclient.com)'), ('HTTP_ACCEPT', '*/*'), ('HTTP_ACCEPT_ENCODING', 'gzip, deflate, br'), ('HTTP_COOKIE', 'access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbiI6Ik5XMXhFVmZvcWpHUG9VZ0M3aEkwWjBrbzFtTjNBdyJ9.G59Jm7yArLY3OOmkQGVA2wDVg_BHXSdKoeAr176CGQc; refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbiI6Ind2dXhUdXc5bFZrZzhROTJpem0xMXlJYVZMZTR4ZSJ9.9FoRcaIj7XYD-c7m_f5N9RD6G24DGDaLrskKpukXtfA; is_authenticated=True; csrftoken=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; sessionid=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'), ('HTTP_HOST', 'localhost:8000'), ('HTTP_CONNECTION', 'close'), ('wsgi.version', (1, 0)), ('wsgi.run_once', False), ('wsgi.url_scheme', 'http'), ('wsgi.multithread', True), ('wsgi.multiprocess', False), ('wsgi.file_wrapper', <class 'wsgiref.util.FileWrapper'>), ('CSRF_COOKIE', 'npCiSfkvcxo0ByfWyjdOJQELZFrxNIUQn0xYQN39s74P32oPtUP0OkiIg8aLbaSI')])

So I went into drf_social_oauth2/views/ConvertTokenView.post() to manually remove the PS1 header from the response headers and it works fine. I know this isn't ideal so I'd like suggestions for a better way. If this is a bug on the module, please get it fixed.

fahedmahidi commented 1 year ago

Thanks for pointing at this patch (I don't know what the PS1 is used for in the response header but at least you can reconnect an existing user).

For anyone trying to remove the PS1 header you have to add

if (k!='PS1'):

just below

for k, v in headers.items():

wagnerdelima commented 1 year ago

image

Are you sure you configured your Google Credentials and the application well? I just created one app for testing purposes and I am using google oauth. As you can see, it passes just fine.

image