I am overwhelmed by the authentication of Django and trying to wrap my head around it for a while.
i have used social-auth-app-Django to use OAuth for authorization from GitHub and Facebook.
GitHub worked and Facebook didn't worked, after log-in using GitHub I checked the admin page,
in the user social auths part i wasn't able to access the provider name using the template syntax in the html Page didn't showed up!
can someone explain what really going on here, and what is associations and nonces too?
this is my html.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{%if user.is_authenticated%}
<h1>{{user.provider}}</h1>
<h1>{{user.username}}</h1>
{%else%}
<h1>you are not logged in</h1>
{%endif%}
</body>
</html>
You can access provider by doing this :
in views.py
def get_provider(request):
user= request.user
user.social_auth.get(provider='provider name')
provs= ['github','twitter','facebook','google-oauth2'] # Any backend in the social auth back end
found=list()
notfound=list()
for prov in provs :
try:
user.social_auth.get(provider=prov)
print("Found ",prov)
found.append(prov)
except:
print(prov,"Not found ")
notfound.append(prov)
return render(request, 'registration/social_login.html', {
'found':found,
'not_found':notfound,
})
Then in your template
social_login.html
{% for element in found %}
<p>you are auth as {{element}}</p>
{% endfor %}
{% for el in not_found %}
<p>you are not auth in {{el}}</p>
{% endfor %}
You can found more here https://simpleisbetterthancomplex.com/tutorial/2016/10/24/how-to-add-social-login-to-django.html
Related
I'm trying to connect Google One Tap Login with Django framework, but I'm having issue.
I'm not sure why this is displaying an issue. I followed all of the guidelines described in the Google documentation.
issue -
The given origin is not allowed for the given client ID
Here is my Google API client configuration for the javascript origin url.
Here is the login html template code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Hi Reddit</h1>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<div id="g_id_onload" data-client_id="i don't want to shere"
data-context="signin" data-ux_mode="popup" data-login_uri="http://localhost:8000/google/login/"
data-auto_select="true" data-itp_support="true">
</div>
<div class="g_id_signin" data-type="standard" data-shape="pill" data-theme="outline" data-text="continue_with"
data-size="large" data-logo_alignment="left">
</div>
</body>
</html>
I'm not sure why this is displaying an issue.
Is it possible to load Google One Tap Javascript in Django?
What should I do to load Google One Tap Javascript in Django?
Just curious why this is working, since haven't found such examples in flask and jinjia2 official docs. It seems include is just simply put the content to the place just as it is, right?
# app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def index():
names = ['John', 'James', 'Jenny']
return render_template('index.html', names=names)
if __name__ == '__main__':
app.run(port=5200)
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
</head>
<body>
Welcome!
<!-- I know this is working as official docs -->
{% for name in names %}
<div class='card'>Welcome {{ name }}!</div>
{% endfor %}
<!-- but haven't found any examples like below, but it works -->
{% for name in names %}
{% include "card.html" %}
{% endfor %}
</body>
</html>
<!-- card.html -->
<div class='card'>Welcome {{ name }}!</div>
code example in vscode
From https://jinja.palletsprojects.com/en/3.0.x/templates/
Include
The include tag is useful to include a template and return the
rendered contents of that file into the current namespace:
{% include 'header.html' %}
Body {% include 'footer.html' %}
Included templates have access to the variables of the active context
by default.
This code will work because cards.html will be reloaded at each step of the "for" loop.
We can include a template in another template in the jinja structure. We don't have to use "for" when doing this.
The list elements to be navigated in the "for" loop are rendered from the flask view. In this way, we can use the rendered list and its elements as we want in the specified template while rendering.
{% for name in names %}
{% include "card.html" %}
{% endfor %}
path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(template_name='registration/password_change_done.html'),
name='password_change_done'),
path('password_change/', auth_views.PasswordChangeView.as_view(template_name='registration/password_change.html'),
name='password_change'),
Here is my two url path. After changing password the new url should be 'password_change/done/' and should show some thing that is in template.
but when I change my password it goes to 'password_change/done/' url but shows something that is default in django saying password change succesful does not show login link that is in template. How can I fix this?
here is my template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="container">
<div class="d-flex flex-column">
<p class="m-auto">Your password has been set. You may go ahead and Login in now.</p>
</div>
</div>
</body>
</html>
You can read the documentations where you can find the correct path for the built in auth system
Django Docs
in your case your urls should be changed to this
path('accounts/password_change/done/', auth_views.PasswordChangeDoneView.as_view(template_name='registration/password_change_done.html'),
name='password_change_done'),
path('accounts/password_change/', auth_views.PasswordChangeView.as_view(template_name='registration/password_change.html'),
name='password_change'),
#you need also to add this to the urlpatterns of your project
path('accounts/', include('django.contrib.auth.urls')),
I want to put an html in a string, NOT a file, like:
t = """
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>foo</title>
</head>
<body>
{{ script|safe }}
</body>
</html>
"""
script = ...
render_template_string(t, script=script)
However when I go to the actual webpage, I don't see an html page with a script, I see garbage:
"\n<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <title>foo</title>\n</head>\n\n<body>\n \n<script\n src=\"http://localhost:5006/bkapp/autoload.js?bokeh-autoload-element=ff639949-97c5-40b8-9cc2-28b78be802d1&bokeh-app-path=/bkapp&bokeh-absolute-url=http://localhost:5006/bkapp\"\n id=\"ff639949-97c5-40b8-9cc2-28b78be802d1\"\n data-bokeh-model-id=\"\"\n data-bokeh-doc-id=\"\"\n></script>\n</body>\n</html>"
How do I fix this?
EDIT: even a very simple
t = '{{ script|safe }}'
does not work, I get, in the browser:
"\n<script\n src=\"http://localhost:5006/bkapp/autoload.js?bokeh-autoload-element=07a43696-66af-4e54-a4e3-9a09ac242e38&bokeh-app-path=/bkapp&bokeh-absolute-url=http://localhost:5006/bkapp\"\n id=\"07a43696-66af-4e54-a4e3-9a09ac242e38\"\n data-bokeh-model-id=\"\"\n data-bokeh-doc-id=\"\"\n></script>"
EDIT 2: I have also tried
t = '{% autoescape false %}{{ script|safe }}{% endautoescape %}'
but that didn't work either.
I'm using Connexion if that matters.
I'm writing my first Django app by following along with this book:
http://chimera.labs.oreilly.com/books/1234000000754/ch05.html#_passing_python_variables_to_be_rendered_in_the_template
In the book there is a test that is verifying that the html is being returned as it is supposed to. Here is the test:
def test_home_page_returns_correct_html(self):
request = HttpRequest()
response = home_page(request)
expected_html = render_to_string('home.html')
print(expected_html)
print(response.content.decode())
self.assertEqual(response.content.decode(), expected_html)
My test is failing on the assertEqual test because I have added a csrf token in my HTML using the Django Template Language. Here is what my HTML page looks like:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>To-Do lists</title>
</head>
<body>
<h1>Your To-Do list</h1>
<form method="POST">
<input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>
{% csrf_token %}
</form>
<table id="id_list_table">
<tr><td>{{ new_item_list }}</td></tr>
</table>
</body>
</html>
My assert is failing due to the render_to_string method not including the token. Here is what my two print statements included in my test print out:
F<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>To-Do lists</title>
</head>
<body>
<h1>Your To-Do list</h1>
<form method="POST">
<input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>
</form>
<table id="id_list_table">
<tr><td></td></tr>
</table>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>To-Do lists</title>
</head>
<body>
<h1>Your To-Do list</h1>
<form method="POST">
<input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>
<input type='hidden' name='csrfmiddlewaretoken' value='VAiGvXZLHCjxWEWdjhgQRBwBSnMVoIWR' />
</form>
<table id="id_list_table">
<tr><td></td></tr>
</table>
</body>
</html>
F.
He doesn't have this problem in the book (he's using 1.8), so I was wondering if the method behavior has changed, or how I would write this test to pass.
The request argument was added to render_to_string in Django 1.8. You could try changing the line in your test to:
expected_html = render_to_string('home.html', request=request)
It's only required to make this change in Django 1.9+, the test passes without the request in Django 1.8.
I found this solution which has worked for the latest Django version - 3.0.6
#add a function to the post request test function
def remove_csrf_tag(text):
"""Remove csrf tag from TEXT"""
return re.sub(r'<[^>]*csrfmiddlewaretoken[^>]*>', '', text)
...
# then change assertion
def test_home_page_can_save_a_POST_request(self):
...
self.assertEqual(
remove_csrf_tag(response.content),
remove_csrf_tag(expected_html)
)