I have developed an app on Google App Engine in Python37 & Flask on the Standard Environment. I have the following file as the index.html for authentication. I have configured the Firebase authentication app to include Google, Email and Facebook authentication. However, the widget only shows Google and Email. None of the other implementations of the Firebase Authentication-UI returns the Token that can be verified in python main.py app.
index.html - I have the correct Firebase config values in my real html file
<!doctype html>
<html>
<head>
<title>Myapp</title>
<link rel="stylesheet" href="/static/bulma.min.css">
<script defer src="/static/all.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.8.4/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "<API_KEY>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
projectId: "<PROJECT_ID>",
storageBucket: "<BUCKET>.appspot.com",
messagingSenderId: "<MESSAGING_SENDER_ID>"
};
firebase.initializeApp(config);
</script>
<script>
if (typeof firebase === 'undefined') {
const msg = "Please paste the Firebase initialization snippet into index.html. See https://console.firebase.google.com > Overview > Add Firebase to your web app.";
console.log(msg);
alert(msg);
}
</script>
<!-- [START gae_python37_auth_include_firebaseui] -->
<script src="https://cdn.firebase.com/libs/firebaseui/2.6.2/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/2.6.2/firebaseui.css">
<!-- [END gae_python37_auth_include_firebaseui] -->
<script src="{{ url_for('static', filename='script.js') }}"></script>
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<br><br><br>
<div class="title is-4 has-text-centered">
<div>
Welcome to Myapp
</div>
</div>
<div class="title is-5 has-text-centered">Myapp</div>
<!-- [START gae_python37_auth_firebase_html] -->
<div id="firebaseui-auth-container"></div>
<button id="sign-out" hidden=true>Sing out</button>
<div id="login-info" hidden=true>
</div>
<!-- [END gae_python37_auth_firebase_html] -->
<!-- Footer Section -->
</body>
</html>
main.py
id_token = request.cookies.get("token")
claims = google.oauth2.id_token.verify_firebase_token(
id_token, firebase_request_adapter)
See below the implementation I did as per this documentation that #Ajordat has referred to. I get a an empty id_token error - Illegal ID token provided: None. ID token must be a non-empty string
enter image description here
Here is the index.html page
<!doctype html>
<html>
<head>
<title>Datastore and Firebase Auth Example</title>
<script src="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css" />
<script src="https://www.gstatic.com/firebasejs/5.8.4/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "<API_KEY>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
projectId: "<PROJECT_ID>",
storageBucket: "<BUCKET>.appspot.com",
messagingSenderId: "<MESSAGING_SENDER_ID>"
};
firebase.initializeApp(config);
</script>
<script>
var uiConfig = {
callbacks: {
signInSuccessWithAuthResult: function(authResult, redirectUrl) {
// User successfully signed in.
// Return type determines whether we continue the redirect automatically
// or whether we leave that to developer to handle.
return true;
},
uiShown: function() {
// The widget is rendered.
// Hide the loader.
document.getElementById('loader').style.display = 'none';
}
},
// Will use popup for IDP Providers sign-in flow instead of the default, redirect.
signInFlow: 'popup',
signInSuccessUrl: '/',
signInOptions: [
// Leave the lines as is for the providers you want to offer your users.
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID
],
// Terms of service url.
tosUrl: '<your-tos-url>',
// Privacy policy url.
privacyPolicyUrl: '<your-privacy-policy-url>'
};
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);
</script>
</head>
<body>
<h1>Datastore and Firebase Auth Example</h1>
<!-- [START gae_python37_auth_firebase_html] -->
<div id="firebaseui-auth-container"></div>
<button id="sign-out" hidden=true>Sign Out</button>
<div id="login-info" hidden=true>
<h2>Login info:</h2>
{% if user_data %}
<dl>
<dt>Name</dt><dd>{{ user_data['name'] }}</dd>
<dt>Email</dt><dd>{{ user_data['email'] }}</dd>
<dt>Last 10 visits</dt><dd>
{% for time in times %}
<p>{{ time['timestamp'] }}</p>
{% endfor %} </dd>
</dl>
{% elif error_message %}
<p>Error: {{ error_message }}</p>
{% endif %}
</div>
User id :{{ uid }}
<br>
User: {{ user.email }}
<br>
Error: {{ error_message }}
<br><br><br>
{{ id_token }}
<!-- [END gae_python37_auth_firebase_html] -->
</body>
</html>
The main.py code for verifying the id_token
...
default_app = firebase_admin.initialize_app()
#app.route('/')
def root():
# Verify Firebase auth.
id_token = request.cookies.get("token")
error_message = ''
uid = None
user = None
# if id_token:
try:
decoded_token = auth.verify_id_token(id_token)
uid = decoded_token['uid']
user = auth.get_user(uid)
except ValueError as exc:
error_message = str(exc)
return render_template(
'index.html',
uid=uid, user=user, error_message = error_message)
The solution was to get the token from authResult.user and set it as a cookie so it can later be retrieved from the server. See the code attached:
signInSuccessWithAuthResult: function(authResult, redirectUrl) {
var user = authResult.user;
var credential = authResult.credential;
var isNewUser = authResult.additionalUserInfo.isNewUser;
var providerId = authResult.additionalUserInfo.providerId;
var operationType = authResult.operationType;
if (user) {
user.getIdToken().then(function (accessToken) {
console.log("token retrieved: " + accessToken);
document.cookie = "token=" + accessToken + "; samesite=Lax";
});
}
return true;
}
Related
Picture 1 Picture 2 Picture 3 I am building a page in Django that first renders a blank page with a loading picture, and then calls an Ajax get function to one of my views. Once my Ajax get function succeeds, it is supposed to load one of my HTML files. I get a 404 error saying that the template cannot be found, but the template is in the same folder as my other file. Is my file path wrong?
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
{% extends "stocks_sites/base.html" %}
<!-- The loading image -->
{% block loader %}
<div id="loading">
<p>Loading</p>
</div>
<div id="articles">
</div>
<script>
// AJAX call when page has loaded
$(document).ready(function(){
$.ajax({
type: "GET",
url: "{% url 'stocks_sites:get_news_articles' %}",
success: function(response) {
const news_articles = response;
const posts = news_articles.posts;
const search = news_articles.search;
document.getElementById("loading").style.display = "none";
$("#articles").load("news_articles.html");
}
});
});
</script>
{% endblock loader %}
#app.route('/')
def index():
users = [[1],[2],[3]]
return render_template('index.html', users=users)
#app.route('/update', methods=['GET', 'POST'])
def update():
print(' post received ')
if request.method == 'POST':
print(request.form['idval']
return jsonify({'result': 'success'})
and this is my simple html
{% block body %}
<body>
{% for user in users %}
<td id='position{{user[0]}}' class='updateposition'></td>
<td id='amount{{user[0]}}' class='updateamount'></td>
{% endfor %}
<script src="http://code.jquery.com/jquery.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="{{ url_for('static', filename='app.js') }}"></script>
</body>
{% endblock %}
and here's my app.js file within static folder which contains the jquery
$(document).ready(function() {
setInterval(ajaxCall, 1000);
function ajaxCall(){
var positionIds = Array.prototype.slice.call(document.querySelectorAll('.updatecurrposition')).map(function ( element ) { return element.id;});
var amountIds = Array.prototype.slice.call(document.querySelectorAll('.updatepositionamount')).map(function ( element ) {return element.id;});
console.log(positionIds[0])
for (i = 0; i < positionIds.length; i++){
req = $.ajax({
url : '/update',
type : 'POST',
data : {idval : positionIds[i]}
});
}
}
and this example was taken from
https://github.com/PrettyPrinted/youtube_video_code/tree/master/2017/03/27/Using%20jQuery%20to%20Update%20a%20Page%20Without%20Refresh%20(Part%201%20of%202)/ajax_without_update
I've literally copied every single tutorials online and tried to implement it in my own (and most of the tutorials themselves fail in my computer for some reason)
and it just seems it can't get the data. I get a proper initial 200 response to get the html template but when the POST request does work, it only shows 304 redirect message, but nothing gets printed in the console
this perhaps seems to be the reason when I try to update the value upon receiving the data from the flask server, nothing happens. i.e.
req.done(function(data){
$('#'+positionIds[i]).text(data.result);
});
adding this right after req = $.ajax seems to change nothing
Does changing the td tags to something like p work? From tests I think that empty td tags aren't generated. I changed the tags and it was printing (to the console) successfully.
I am new to angularjs,i try a demo test for routing ,below is my codes
app.js
var app=angular.module("tutorialApp",["ngRoute","tutorialCtrlModule"]);
app.config(function($routeProvider){
$routeProvider
.when("/",{
templateUrl:"views/tutorial.html",
controller:"TutorialCtrl"
})
.when("/tutorialsecond",{
templateUrl:"views/tutorialSecond.html",
controller:"TutorialCtrl2"
});
});
tutorialCtrl.js
angular.module("tutorialCtrlModule",[])
.controller("TutorialCtrl",["$scope",function($scope){
$scope.name = 'dipti';
$scope.bindvalue = 2;
$scope.timesTwo = function(){
$scope.bindvalue *=2;
}
}])
.controller("TutorialCtrl2",["$scope",function($scope){
$scope.name = 'Dipti';
}]);
index.html
<html ng-app="tutorialApp">
<head>
<meta charset="utf-8">
<title>Tutorial App</title>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js">
</script>
<script src="lib/angular-route.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/tutorialCtrl.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
this is my routing pages
tutorial.html
<u><h3>Route Page</h3></u>
<u>Expression</u>
<br>
{{ name }}
<br>
<u>Data Binding</u>
<br>
<label>Name</label>
<br>
<input ng-model="name">
<br>
<p>My first expression: {{ 5 + 1 }}</p>
<br>
Tutorial Second Page
When i load my project the default page tutorial.html will show,but ! sign will come in my url like http://localhost/Angular_demo/#!/
When i click on link in tutorial.html page for routing it not working and this url will show http://localhost/Angular_demo/#!/#%2Ftutorialsecond.How i will slove it.
Configure your hash prefix correctly
angular.module('myApp').config([
'$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix(''); // or whatever you want
}
]);
Extra:
make sure html5mode is active
$locationProvider.html5Mode(true);
and that your base is set
<base href"/"/>
I am a new Frond-end developer learning "Mithril JS". I created sample login page using MVC Pattern. The login form is not working after console error:
Uncaught TypeError: vm.name is not a function
How to resolve this issue?
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Mithril Js</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="bower_components/todomvc-common/base.css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="bower_components/mithril/mithril.min.js"></script>
<script src="bower_components/todomvc-common/base.js"></script>
</head>
<body>
<section id="MitApp"></section>
<script src="js/app.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="js/views/login.js"></script>
<script src="js/controllers/todos.js"></script>
</body>
</html>
App.Js (create route map)
var app = app || {};
(function(window){
'use strict';
app.ENTER_KEY = 13;
app.ESC_KEY = 27;
m.route.mode = "hash";
m.route(document.getElementById('MitApp'), '/', {
"/":app,
"/:filter":app
});
})(window);
Login Form
var app = app || {};
app.view = function(ctrl){
var vm = app;
console.log(vm);
return[m(".container", {style: {"margin-top": "55px"}}, [
m(".col-md-4.col-md-offset-4", [
m("h4", "Login"),
m("form[action=''][enctype='multipart/form-data'][method='post']", [
m(".form-group", [
m("input.form-control[placeholder='Username'][type='name']", {value:vm.name(), onchange:m.writeAttr("value", vm.name)})
]),
m(".form-group", [
m("input.form-control[placeholder='Password'][type='password']", {value:vm.password(), onchange:m.writeAttr("value",vm.password)})
]),
m(".form-group", [
m("button.btn.btn-primary.pull-right[id='login'][type='submit']",{onclick:vm.submit.bind(vm)}, "Login")
])
])
]),
"\
"
])]
}
Simply, your app.view function in your login form contains a reference to vm.name, but none of the code you've posted here defines what vm.name is. The second line of the function is console.log(vm) — so you should be able to open your browser console and see what vm is. I can see that vm is a reference to app, and by reading the rest of your code I can see the following references attached:
app.ENTER_KEY = 13;
app.ESC_KEY = 27;
app.view = function(){/**/}
As far as I can see, those are the only properties set on app / vm, but when I read the contents of the app.view function, I can see that it expects the following extra properties to be available:
vm.name
vm.password
vm.submit
vm.name and vm.password look like m.props, and vm.submit is obviously a function (it's clear what you expect it to do - log in the user - but I can't know how you expect to do that). So the way to make the view execute properly would be to define those properties. I'll define these in the same place you defined app.ENTER_KEY and app.ESC_KEY - in App.js - because that seems to be where you want to keep your model:
var app = app || {};
(function(window){
'use strict';
app.ENTER_KEY = 13;
app.ESC_KEY = 27;
// Define the extra properties needed for your view:
app.name = m.prop( '' )
app.password = m.prop( '' )
app.submit = function(){
// ...
}
m.route.mode = "hash";
m.route(document.getElementById('MitApp'), '/', {
"/":app,
"/:filter":app
});
})(window);
I am trying to add markdown to my input text box for a flask project. I am following the Grinburg text book. In my forms.py I have :
from flask_pagedown.fields import PageDownField
from wtforms.fields.simple import HiddenField
class NewEntry(Form):
'''
A form for new entries
'''
title = TextAreaField("Title", validators=[Required()])
text = PageDownField("Text", validators=[Required()])
tags = TextAreaField("Tags", validators=[Required()])
srcLibEntries = HiddenField(label=None, id="srcLibArticles")
submit = SubmitField('Submit', id="new_entry_submit_button")
Over in my HTML, I have :
{% extends "layout.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block scripts %}
{{super()}}
{{pagedown.include_pagedown()}}
{% endblock %}
{% block body %}
<form method="post" role="form">
{{ wtf.form_field(form.title) }}
{{ wtf.form_field(form.text) }}
{{ wtf.form_field(form.tags) }}
{{ form.srcLibEntries }}
{{ wtf.form_field(form.submit) }}
</form>
All this unfurls at the browser to have the following code for the text input box :
<div class="form-group required"><label class="control-label" for="text">Text</label>
<div class="flask-pagedown"><textarea class="form-control flask-pagedown-input" id="flask-pagedown-text" name="text" required>fsdafds</textarea></div>
<div class="flask-pagedown-preview" id="flask-pagedown-text-preview"></div>
<script type="text/javascript">
f = function() {
if (typeof flask_pagedown_converter === "undefined")
flask_pagedown_converter = Markdown.getSanitizingConverter().makeHtml;
var textarea = document.getElementById("flask-pagedown-text");
var preview = document.getElementById("flask-pagedown-text-preview");
textarea.onkeyup = function() { preview.innerHTML = flask_pagedown_converter(textarea.value); }
textarea.onkeyup.call(textarea);
}
if (document.readyState === 'complete')
f();
else if (window.addEventListener)
window.addEventListener("load", f, false);
else if (window.attachEvent)
window.attachEvent("onload", f);
else
f();
</script>
</div>
I am getting an exception at the browser, namely, "Uncaught ReferenceError: Markdown is not defined" and it is referring to this line :
flask_pagedown_converter = Markdown.getSanitizingConverter().makeHtml;
I don't think I have to import any more markdown anywhere. What is going on here?
Edit 1:
I needed to add the following to my layout.css:
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Converter.js"> </script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Editor.js"> </script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Sanitizer.js"> </script>
I needed to add the following to my layout.css:
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Converter.js"> </script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Editor.js"> </script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Sanitizer.js"> </script>