Flask-Login User Authentication lufy November 21, 2022 <p>Original link: <a href="https://www.askpython.com/python-modules/flask/flask-user-authentication">https://www.askpython.com/python-modules/flask/flask-user-authentication</a></p> <header class="entry-header ast-no-meta"> <div class="ast-single-post-order"> <h1 class="entry-title">Flask User Authentication – How to Setup User Login in Flask?</h1> </div> </header> <div class="entry-content clear"> <div class="code-block code-block-1"> <div id="00000001-5925667b-15cc-4aef-9b63-2dff73108c3d" class="_ap_apex_ad" data-section="00000001-5925667b-15cc-4aef-9b63-2dff73108c3d" data-orig-id="047c75ae-770e-46a1-a341-a6ba8a41ccc2" data-render-time="1668991059715" data-ap-network="adpTags" data-refresh-time="1669045922603" data-timeout="188248"> <div id="ADP_41988_responsivexresponsive_00000001-5925667b-15cc-4aef-9b63-2dff73108c3d" data-google-query-id="CMuIk8zQv_sCFadhDwIda28Lcg"> <div id="google_ads_iframe_/103512698,14629573/22813003725_0__container__">In this article, we will code Flask user authentication using the Flask-Login Library and SQLAlchemy. So let’s get started!</div> </div> </div> </div> <p>Nowadays, almost all the websites have user authentication systems coded into them. We can set-up an account with user authentication either directly or via a third-party like Google, Facebook. Apple etc.</p> <p>A typical user login page looks like this:</p> <div class="code-block code-block-8"> <div id="00000001-38634c20-2231-4b39-bb7a-683a5c9084b2" class="_ap_apex_ad" data-section="00000001-38634c20-2231-4b39-bb7a-683a5c9084b2" data-orig-id="af47fad2-c8fd-4aa1-9acb-0492738779a5" data-render-time="1668991059722"> <div id="videoAdSlot"> <div id="primisPlayerContainerDiv" class="primisslate"> <div id="primis_container_div"> <div id="primis_playerSekindoSPlayer637ac854f07aa"> <div id="Player-Div-SekindoSPlayer637ac854f07aa"> <div id="Video-Div-SekindoSPlayer637ac854f07aa"> <div id="Video-iFrame-SekindoSPlayer637ac854f07aa"> <div id="layoutContainerDiv"> <div id="layoutDesign"> <div id="topRightElements"> <div id="primisLogoWrapper"> <div id="primisLogo"> <div id="pl1"></div> <div id="primisLogoTxt"> <div id="pl2"></div> </div> <div id="pl3"></div> </div> </div> </div> </div> </div> <div id="adBreakDiv"> <div id="adBreakPreloader"></div> </div> </div> <div id="pixelsDiv"></div> </div> </div> </div> </div> </div> </div> </div> </div> <div class="wp-block-image"> <figure class="aligncenter"><img class="entered litespeed-loaded" src="https://www.askpython.com/wp-content/uploads/2020/08/image-28.png.webp" alt="Django User Authentication - Allow Signup and Login Using Django - AskPython" width="671" height="677" data-lazyloaded="1" data-src="https://www.askpython.com/wp-content/uploads/2020/08/image-28.png.webp" data-ll-status="loaded" /> <figcaption>User Login Page</figcaption> </figure> </div> <p>User authentication is an essential part of the webpage since it protects user data such that only that particular user can access it. There are different ways to authenticate a user:</p> <ol> <li>Cookie-based authentication</li> <li>token-based authentication</li> <li>OAuth authentication</li> <li>OpenId</li> <li>Saml</li> </ol> <p>We will now code using Flask-Login authentication. So let’s dive into the coding part.</p> <div class="code-block code-block-2"> <div id="00000001-8be77117-b1db-4f27-928f-b91721f5a750" class="_ap_apex_ad" data-section="00000001-8be77117-b1db-4f27-928f-b91721f5a750" data-orig-id="4153c0c9-28de-44dc-9271-1c1855855c09" data-render-time="1668991059726" data-ap-network="adpTags" data-refresh-time="1669046018438" data-timeout="189406"> <div id="ADP_41988_responsivexresponsive_00000001-8be77117-b1db-4f27-928f-b91721f5a750" data-google-query-id="CKP_7PnQv_sCFRlLDwIdCL8NjA"> <div id="google_ads_iframe_/103512698,14629573/22813005063_0__container__"><strong>Hands-On with Flask User Authentication</strong></div> </div> </div> </div> <p><strong>Flask-login</strong> uses Cookie-based Authentication. When the client logins via his credentials, Flask creates a session containing the <strong>user ID</strong> and then sends the <strong>session ID </strong>to the user via a cookie, using which he can log in and out as and when required.</p> <p>First we need to install the <strong>Flask-Login</strong></p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_606721" class="syntaxhighlighter nogutter bash"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="bash plain">pip </code><code class="bash functions">install</code> <code class="bash plain">flask-login</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Now that it’s installed, let’s move into the coding part!</p> <h2>1. Coding the models.py file</h2> <p>First, we will create the <strong>User Model</strong> to store user credentials. We will use Flask_SQLAlchemy and SQLite Database to do this.</p> <div class="code-block code-block-3"> <div id="00000001-8980d4db-e5af-4f1f-923b-1f235b4dbdec" class="_ap_apex_ad" data-section="00000001-8980d4db-e5af-4f1f-923b-1f235b4dbdec" data-orig-id="03dec052-3fc4-4753-88e1-b2bb64738009" data-render-time="1668991059728" data-ap-network="adpTags" data-refresh-time="1669046134463" data-timeout="190757"> <div id="ADP_41988_responsivexresponsive_00000001-8980d4db-e5af-4f1f-923b-1f235b4dbdec" data-google-query-id="CIq1lrHRv_sCFYNlDwIdsmAGJg"> <div id="google_ads_iframe_/103512698,14629573/22813005072_4__container__">One Important thing to note here is that <strong>we cannot save the user passwords</strong> directly on the database because if some hacker gets access to our site, he will be able to retrieve all the information from the database.</div> </div> </div> </div> <p>So we cannot afford that. But don’t worry, Flask werkzeug has inbuilt functions to deal with this problem.</p> <h3>1.1 Setup a Password Hash</h3> <p>The solution is to use a <strong>Password Hash</strong>. Let us see what a hash is, so go to the python shell in the terminal and run the command</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_256287" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">werkzeug.security </code><code class="python keyword">import</code> <code class="python plain">generate_password_hash</code></div> <div class="line number2 index1 alt1"><code class="python plain">a </code><code class="python keyword">=</code> <code class="python plain">generate_password_hash(</code><code class="python string">'1234'</code><code class="python plain">)</code></div> <div class="line number3 index2 alt2"><code class="python functions">print</code><code class="python plain">(a)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>We will get a long random string as shown below:</p> <div class="wp-block-image"> <figure class="aligncenter size-large"><img class="wp-image-8960 entered litespeed-loaded" src="https://www.askpython.com/wp-content/uploads/2020/09/image-83.png" sizes="(max-width: 895px) 100vw, 895px" srcset="https://www.askpython.com/wp-content/uploads/2020/09/image-83.png 895w, https://www.askpython.com/wp-content/uploads/2020/09/image-83-300x29.png.webp 300w, https://www.askpython.com/wp-content/uploads/2020/09/image-83-768x75.png.webp 768w" alt="Password Hash" width="895" height="87" data-lazyloaded="1" data-src="https://www.askpython.com/wp-content/uploads/2020/09/image-83.png" data-srcset="https://www.askpython.com/wp-content/uploads/2020/09/image-83.png 895w, https://www.askpython.com/wp-content/uploads/2020/09/image-83-300x29.png.webp 300w, https://www.askpython.com/wp-content/uploads/2020/09/image-83-768x75.png.webp 768w" data-sizes="(max-width: 895px) 100vw, 895px" data-ll-status="loaded" /> <figcaption>Password Hash</figcaption> </figure> </div> <p>Hence even if the hacker gets access to them, he won’t be able to decrypt. Also, we have another function to compare the Hash with a password, called <strong>check_password_hash</strong>.</p> <div class="code-block code-block-3"> <div id="00000001-e9d3bdb5-50e0-4112-bd4f-aa8992b36328" class="_ap_apex_ad" data-section="00000001-e9d3bdb5-50e0-4112-bd4f-aa8992b36328" data-orig-id="03dec052-3fc4-4753-88e1-b2bb64738009" data-render-time="1668991059734" data-ap-network="adpTags" data-refresh-time="1669042395530" data-timeout="183189"> <div id="ADP_41988_responsivexresponsive_00000001-e9d3bdb5-50e0-4112-bd4f-aa8992b36328" data-google-query-id="CPX4qbrDv_sCFWJeDwIdvLUPsw"> <div id="google_ads_iframe_/103512698,14629573/22813005069_8__container__">It works as below:</div> </div> </div> </div> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_384903" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">werkzeug.security </code><code class="python keyword">import</code> <code class="python plain">generate_password_hash, check_password_hash</code></div> <div class="line number2 index1 alt1"><code class="python plain">a </code><code class="python keyword">=</code> <code class="python plain">generate_password_hash(</code><code class="python string">'1234'</code><code class="python plain">)</code></div> <div class="line number3 index2 alt2"><code class="python functions">print</code><code class="python plain">(a)</code></div> <div class="line number4 index3 alt1"> </div> <div class="line number5 index4 alt2"><code class="python plain">chech_password_hash(a,</code><code class="python string">'1234'</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Now hit enter, it will return <strong>True</strong> if matched and<strong> False</strong> if unmatched.</p> <div class="wp-block-image"> <figure class="aligncenter size-large"><img class="wp-image-8961 entered litespeed-loaded" src="https://www.askpython.com/wp-content/uploads/2020/09/image-84.png" sizes="(max-width: 863px) 100vw, 863px" srcset="https://www.askpython.com/wp-content/uploads/2020/09/image-84.png 863w, https://www.askpython.com/wp-content/uploads/2020/09/image-84-300x58.png.webp 300w, https://www.askpython.com/wp-content/uploads/2020/09/image-84-768x150.png.webp 768w" alt="Password Hash" width="863" height="168" data-lazyloaded="1" data-src="https://www.askpython.com/wp-content/uploads/2020/09/image-84.png" data-srcset="https://www.askpython.com/wp-content/uploads/2020/09/image-84.png 863w, https://www.askpython.com/wp-content/uploads/2020/09/image-84-300x58.png.webp 300w, https://www.askpython.com/wp-content/uploads/2020/09/image-84-768x150.png.webp 768w" data-sizes="(max-width: 863px) 100vw, 863px" data-ll-status="loaded" /> <figcaption>Password Hash</figcaption> </figure> </div> <h3>1.2 Adding Hashed Passwords to Your Database</h3> <p>Also if you don’t have <a class="rank-math-link" href="https://www.askpython.com/python-modules/flask/flask-postgresql"><span class="_ap_link_preview" data-preview-variation="relatedPostsPage" data-attribute="FlaskSQLAlchemy" data-url="https://www.askpython.com/python-modules/flask/flask-postgresql">FlaskSQLAlchemy</span></a>, simply install it using the <a class="rank-math-link" href="https://www.askpython.com/python-modules/python-pip"><span class="_ap_link_preview" data-preview-variation="relatedPostsPage" data-attribute="pip command" data-url="https://www.askpython.com/python-modules/python-pip">pip command</span></a>:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_406614" class="syntaxhighlighter nogutter bash"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="bash plain">pip </code><code class="bash functions">install</code> <code class="bash plain">flask-sqlalchemy</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Okay, now that SQLAlchemy is in place, create a file <strong>models.py</strong> and add the code:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_514980" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask_sqlalchemy </code><code class="python keyword">import</code> <code class="python plain">SQLAlchemy</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">werkzeug.security </code><code class="python keyword">import</code> <code class="python plain">generate_password_hash, check_password_hash</code></div> <div class="line number3 index2 alt2"><code class="python keyword">from</code> <code class="python plain">flask_login </code><code class="python keyword">import</code> <code class="python plain">UserMixin</code></div> <div class="line number4 index3 alt1"> </div> <div class="line number5 index4 alt2"><code class="python plain">db </code><code class="python keyword">=</code> <code class="python plain">SQLAlchemy()</code></div> <div class="line number6 index5 alt1"> </div> <div class="line number7 index6 alt2"><code class="python keyword">class</code> <code class="python plain">UserModel(UserMixin, db.Model):</code></div> <div class="line number8 index7 alt1"><code class="python spaces"> </code><code class="python plain">__tablename__ </code><code class="python keyword">=</code> <code class="python string">'users'</code></div> <div class="line number9 index8 alt2"> </div> <div class="line number10 index9 alt1"><code class="python spaces"> </code><code class="python functions">id</code> <code class="python keyword">=</code> <code class="python plain">db.Column(db.Integer, primary_key</code><code class="python keyword">=</code><code class="python color1">True</code><code class="python plain">)</code></div> <div class="line number11 index10 alt2"><code class="python spaces"> </code><code class="python plain">email </code><code class="python keyword">=</code> <code class="python plain">db.Column(db.String(</code><code class="python value">80</code><code class="python plain">), unique</code><code class="python keyword">=</code><code class="python color1">True</code><code class="python plain">)</code></div> <div class="line number12 index11 alt1"><code class="python spaces"> </code><code class="python plain">username </code><code class="python keyword">=</code> <code class="python plain">db.Column(db.String(</code><code class="python value">100</code><code class="python plain">))</code></div> <div class="line number13 index12 alt2"><code class="python spaces"> </code><code class="python plain">password_hash </code><code class="python keyword">=</code> <code class="python plain">db.Column(db.String())</code></div> <div class="line number14 index13 alt1"> </div> <div class="line number15 index14 alt2"><code class="python spaces"> </code><code class="python keyword">def</code> <code class="python plain">set_password(</code><code class="python color1">self</code><code class="python plain">,password):</code></div> <div class="line number16 index15 alt1"><code class="python spaces"> </code><code class="python color1">self</code><code class="python plain">.password_hash </code><code class="python keyword">=</code> <code class="python plain">generate_password_hash(password)</code></div> <div class="line number17 index16 alt2"><code class="python spaces"> </code> </div> <div class="line number18 index17 alt1"><code class="python spaces"> </code><code class="python keyword">def</code> <code class="python plain">check_password(</code><code class="python color1">self</code><code class="python plain">,password):</code></div> <div class="line number19 index18 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">check_password_hash(</code><code class="python color1">self</code><code class="python plain">.password_hash,password)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Here:</p> <ul> <li>We are storing the <strong>email</strong>, <strong>username,</strong> and password hash</li> <li>Also, we will define 2 class methods – <strong>set_password</strong> to generate the password hash and <strong>check_password</strong> to compare them</li> </ul> <p>We also use a UserMixin from the flask_login library. UserMixin has some inbuilt functions which we will use later:</p> <ul> <li><strong>is_authenticated: </strong>Return<strong> True</strong> if the user has Valid credentials</li> <li><strong>is_active:</strong> Returns <strong>True</strong> if the user’s account is active. Eg- All disabled accounts on Instagram will return <strong>False.</strong></li> <li><strong>is_anonymous:</strong> Returns <strong>False</strong> for regular users and <strong>True</strong> for first-timers/anonymous users</li> <li><strong>get_id():</strong> Returns a unique identifier for a user as a string.</li> </ul> <h3>1.3. Setting the Flask_login Extension</h3> <p>Also, we need to create and initialize the Flask_login extension. We do it using the code:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_376825" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask_login </code><code class="python keyword">import</code> <code class="python plain">LoginManager</code></div> <div class="line number2 index1 alt1"> </div> <div class="line number3 index2 alt2"><code class="python comments">#...</code></div> <div class="line number4 index3 alt1"><code class="python plain">login </code><code class="python keyword">=</code> <code class="python plain">LoginManager()</code></div> <div class="line number5 index4 alt2"><code class="python comments">#...</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>As we discussed earlier, Flask stores the <strong>User ID</strong> of the logged-in users in the session. Since Flask_Login knows nothing about databases, we need to create a function to link both of them.</p> <p>This is done using <strong>user_loader </strong>function. The syntax is:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_328892" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask_login </code><code class="python keyword">import</code> <code class="python plain">LoginManager</code></div> <div class="line number2 index1 alt1"><code class="python plain">login </code><code class="python keyword">=</code> <code class="python plain">LoginManager()</code></div> <div class="line number3 index2 alt2"> </div> <div class="line number4 index3 alt1"><code class="python decorator">@login</code><code class="python plain">.user_loader</code></div> <div class="line number5 index4 alt2"><code class="python keyword">def</code> <code class="python plain">load_user(</code><code class="python functions">id</code><code class="python plain">):</code></div> <div class="line number6 index5 alt1"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">UserModel.query.get(</code><code class="python functions">int</code><code class="python plain">(</code><code class="python functions">id</code><code class="python plain">))</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <h3>1.4. Complete Code</h3> <p>That’s it with the <strong>models.py</strong> part. Let us just look at the whole code once:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_931660" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask_sqlalchemy </code><code class="python keyword">import</code> <code class="python plain">SQLAlchemy</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">flask_login </code><code class="python keyword">import</code> <code class="python plain">UserMixin</code></div> <div class="line number3 index2 alt2"><code class="python keyword">from</code> <code class="python plain">werkzeug.security </code><code class="python keyword">import</code> <code class="python plain">generate_password_hash, check_password_hash</code></div> <div class="line number4 index3 alt1"><code class="python keyword">from</code> <code class="python plain">flask_login </code><code class="python keyword">import</code> <code class="python plain">LoginManager</code></div> <div class="line number5 index4 alt2"> </div> <div class="line number6 index5 alt1"><code class="python plain">login </code><code class="python keyword">=</code> <code class="python plain">LoginManager()</code></div> <div class="line number7 index6 alt2"><code class="python plain">db </code><code class="python keyword">=</code> <code class="python plain">SQLAlchemy()</code></div> <div class="line number8 index7 alt1"> </div> <div class="line number9 index8 alt2"><code class="python keyword">class</code> <code class="python plain">UserModel(UserMixin, db.Model):</code></div> <div class="line number10 index9 alt1"><code class="python spaces"> </code><code class="python plain">__tablename__ </code><code class="python keyword">=</code> <code class="python string">'users'</code></div> <div class="line number11 index10 alt2"> </div> <div class="line number12 index11 alt1"><code class="python spaces"> </code><code class="python functions">id</code> <code class="python keyword">=</code> <code class="python plain">db.Column(db.Integer, primary_key</code><code class="python keyword">=</code><code class="python color1">True</code><code class="python plain">)</code></div> <div class="line number13 index12 alt2"><code class="python spaces"> </code><code class="python plain">email </code><code class="python keyword">=</code> <code class="python plain">db.Column(db.String(</code><code class="python value">80</code><code class="python plain">), unique</code><code class="python keyword">=</code><code class="python color1">True</code><code class="python plain">)</code></div> <div class="line number14 index13 alt1"><code class="python spaces"> </code><code class="python plain">username </code><code class="python keyword">=</code> <code class="python plain">db.Column(db.String(</code><code class="python value">100</code><code class="python plain">))</code></div> <div class="line number15 index14 alt2"><code class="python spaces"> </code><code class="python plain">password_hash </code><code class="python keyword">=</code> <code class="python plain">db.Column(db.String())</code></div> <div class="line number16 index15 alt1"> </div> <div class="line number17 index16 alt2"><code class="python spaces"> </code><code class="python keyword">def</code> <code class="python plain">set_password(</code><code class="python color1">self</code><code class="python plain">,password):</code></div> <div class="line number18 index17 alt1"><code class="python spaces"> </code><code class="python color1">self</code><code class="python plain">.password_hash </code><code class="python keyword">=</code> <code class="python plain">generate_password_hash(password)</code></div> <div class="line number19 index18 alt2"><code class="python spaces"> </code> </div> <div class="line number20 index19 alt1"><code class="python spaces"> </code><code class="python keyword">def</code> <code class="python plain">check_password(</code><code class="python color1">self</code><code class="python plain">,password):</code></div> <div class="line number21 index20 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">check_password_hash(</code><code class="python color1">self</code><code class="python plain">.password_hash,password)</code></div> <div class="line number22 index21 alt1"> </div> <div class="line number23 index22 alt2"> </div> <div class="line number24 index23 alt1"><code class="python decorator">@login</code><code class="python plain">.user_loader</code></div> <div class="line number25 index24 alt2"><code class="python keyword">def</code> <code class="python plain">load_user(</code><code class="python functions">id</code><code class="python plain">):</code></div> <div class="line number26 index25 alt1"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">UserModel.query.get(</code><code class="python functions">int</code><code class="python plain">(</code><code class="python functions">id</code><code class="python plain">))</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Do check out our<a class="rank-math-link" href="https://www.askpython.com/python-modules/flask/flask-postgresql"><span class="_ap_link_preview" data-preview-variation="relatedPostsPage" data-attribute=" SQLAlchemy" data-url="https://www.askpython.com/python-modules/flask/flask-postgresql"> SQLAlchemy</span></a> Article if you are unfamiliar with Flask SQLAlchemy.</p> <h2>2. Coding our main Flask application file</h2> <p>Now let’s code our main <a class="rank-math-link" href="https://www.askpython.com/python-modules/flask/create-hello-world-in-flask"><span class="_ap_link_preview" data-preview-variation="relatedPostsPage" data-attribute="Flask Application" data-url="https://www.askpython.com/python-modules/flask/create-hello-world-in-flask">Flask Application</span></a> File.</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_508041" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask</code></div> <div class="line number2 index1 alt1"><code class="python spaces"> </code> </div> <div class="line number3 index2 alt2"><code class="python plain">app </code><code class="python keyword">=</code><code class="python plain">Flask(__name__)</code></div> <div class="line number4 index3 alt1"><code class="python spaces"> </code> </div> <div class="line number5 index4 alt2"><code class="python plain">app.run(host</code><code class="python keyword">=</code><code class="python string">'localhost'</code><code class="python plain">, port</code><code class="python keyword">=</code><code class="python value">5000</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <h3>2.1 Linking Database to our Flask File</h3> <p>Okay now we need to link our SQLite database with SQLALchemy. So for that add the code:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_710432" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask</code></div> <div class="line number2 index1 alt1"><code class="python spaces"> </code> </div> <div class="line number3 index2 alt2"><code class="python plain">app </code><code class="python keyword">=</code><code class="python plain">Flask(__name__)</code></div> <div class="line number4 index3 alt1"><code class="python plain">app.config[</code><code class="python string">'SQLALCHEMY_DATABASE_URI'</code><code class="python plain">] </code><code class="python keyword">=</code> <code class="python string">'sqlite:///<db_name>.db'</code></div> <div class="line number5 index4 alt2"><code class="python plain">app.config[</code><code class="python string">'SQLALCHEMY_TRACK_MODIFICATIONS'</code><code class="python plain">] </code><code class="python keyword">=</code> <code class="python color1">False</code></div> <div class="line number6 index5 alt1"><code class="python spaces"> </code> </div> <div class="line number7 index6 alt2"><code class="python plain">app.run(host</code><code class="python keyword">=</code><code class="python string">'localhost'</code><code class="python plain">, port</code><code class="python keyword">=</code><code class="python value">5000</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Just replace <strong><db_name></strong> with whatever name you want. Also, we need to link our SQLAlchemy DB instance (present in <strong>models.py </strong>file) with the main app. For that, add:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_583220" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">models </code><code class="python keyword">import</code> <code class="python plain">db</code></div> <div class="line number3 index2 alt2"> </div> <div class="line number4 index3 alt1"><code class="python plain">app </code><code class="python keyword">=</code><code class="python plain">Flask(__name__)</code></div> <div class="line number5 index4 alt2"><code class="python plain">app.config[</code><code class="python string">'SQLALCHEMY_DATABASE_URI'</code><code class="python plain">] </code><code class="python keyword">=</code> <code class="python string">'sqlite:///<db_name>.db'</code></div> <div class="line number6 index5 alt1"><code class="python plain">app.config[</code><code class="python string">'SQLALCHEMY_TRACK_MODIFICATIONS'</code><code class="python plain">] </code><code class="python keyword">=</code> <code class="python color1">False</code></div> <div class="line number7 index6 alt2"><code class="python spaces"> </code> </div> <div class="line number8 index7 alt1"><code class="python plain">db.init_app(app)</code></div> <div class="line number9 index8 alt2"><code class="python plain">app.run(host</code><code class="python keyword">=</code><code class="python string">'localhost'</code><code class="python plain">, port</code><code class="python keyword">=</code><code class="python value">5000</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Now we must add the code to create the database file before the first user request itself. We do that as follows:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_608463" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">models </code><code class="python keyword">import</code> <code class="python plain">db</code></div> <div class="line number3 index2 alt2"><code class="python spaces"> </code> </div> <div class="line number4 index3 alt1"><code class="python plain">app </code><code class="python keyword">=</code><code class="python plain">Flask(__name__)</code></div> <div class="line number5 index4 alt2"><code class="python plain">app.config[</code><code class="python string">'SQLALCHEMY_DATABASE_URI'</code><code class="python plain">] </code><code class="python keyword">=</code> <code class="python string">'sqlite:///<db_name>.db'</code></div> <div class="line number6 index5 alt1"><code class="python plain">app.config[</code><code class="python string">'SQLALCHEMY_TRACK_MODIFICATIONS'</code><code class="python plain">] </code><code class="python keyword">=</code> <code class="python color1">False</code></div> <div class="line number7 index6 alt2"><code class="python spaces"> </code> </div> <div class="line number8 index7 alt1"><code class="python plain">db.init_app(app)</code></div> <div class="line number9 index8 alt2"><code class="python decorator">@app</code><code class="python plain">.before_first_request</code></div> <div class="line number10 index9 alt1"><code class="python keyword">def</code> <code class="python plain">create_table():</code></div> <div class="line number11 index10 alt2"><code class="python spaces"> </code><code class="python plain">db.create_all()</code></div> <div class="line number12 index11 alt1"> </div> <div class="line number13 index12 alt2"><code class="python plain">app.run(host</code><code class="python keyword">=</code><code class="python string">'localhost'</code><code class="python plain">, port</code><code class="python keyword">=</code><code class="python value">5000</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Now everything with the DB part is over. Let’s now move on to the Flask_login Part</p> <h3>2.2 Adding User Authentication to our app</h3> <p>Similar to the DB instance, we must link the <strong>login</strong> instance to our app as well. We do it using:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_466748" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">models </code><code class="python keyword">import</code> <code class="python plain">login</code></div> <div class="line number3 index2 alt2"> </div> <div class="line number4 index3 alt1"><code class="python plain">app </code><code class="python keyword">=</code><code class="python plain">Flask(__name__)</code></div> <div class="line number5 index4 alt2"> </div> <div class="line number6 index5 alt1"><code class="python plain">login.init_app(app)</code></div> <div class="line number7 index6 alt2"> </div> <div class="line number8 index7 alt1"><code class="python plain">app.run(host</code><code class="python keyword">=</code><code class="python string">'localhost'</code><code class="python plain">, port</code><code class="python keyword">=</code><code class="python value">5000</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>After that, we tell Flask_login about the page; the unauthenticated users will get redirected, which will be nothing but the login page itself.</p> <p>Hence add the code:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_114157" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">models </code><code class="python keyword">import</code> <code class="python plain">login</code></div> <div class="line number3 index2 alt2"><code class="python spaces"> </code> </div> <div class="line number4 index3 alt1"><code class="python plain">app </code><code class="python keyword">=</code><code class="python plain">Flask(__name__)</code></div> <div class="line number5 index4 alt2"> </div> <div class="line number6 index5 alt1"><code class="python plain">login.init_app(app)</code></div> <div class="line number7 index6 alt2"><code class="python plain">login.login_view </code><code class="python keyword">=</code> <code class="python string">'login'</code></div> <div class="line number8 index7 alt1"> </div> <div class="line number9 index8 alt2"><code class="python plain">app.run(host</code><code class="python keyword">=</code><code class="python string">'localhost'</code><code class="python plain">, port</code><code class="python keyword">=</code><code class="python value">5000</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>After the redirect page is mentioned, we can simply add the <strong>@login_required</strong> decorator to all the webpage views that will need authentication.</p> <div class="code-block code-block-3"> <div id="00000001-1a443732-515c-4431-9b35-430716fd4e16" class="_ap_apex_ad" data-section="00000001-1a443732-515c-4431-9b35-430716fd4e16" data-orig-id="03dec052-3fc4-4753-88e1-b2bb64738009" data-render-time="1668991059744" data-ap-network="adpTags" data-refresh-time="1669003887371" data-timeout="140070"> <div id="ADP_41988_responsivexresponsive_00000001-1a443732-515c-4431-9b35-430716fd4e16" data-google-query-id="CMKkloC0vvsCFSNZDwId3IoDIA"> <div id="google_ads_iframe_/103512698,14629573/22813005345_0__container__">Cool! Now the only thing that is left is the <strong>login, register, and logout </strong>views. But before that, let us code a simple page that the users can see after authentication</div> </div> </div> </div> <h3>2.3 Coding a Simple View</h3> <p>Hence add a simple view:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_631471" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask, render_template</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">flask_login </code><code class="python keyword">import</code> <code class="python plain">login_required</code></div> <div class="line number3 index2 alt2"> </div> <div class="line number4 index3 alt1"><code class="python decorator">@app</code><code class="python plain">.route(</code><code class="python string">'/blogs'</code><code class="python plain">)</code></div> <div class="line number5 index4 alt2"><code class="python decorator">@login_required</code></div> <div class="line number6 index5 alt1"><code class="python keyword">def</code> <code class="python plain">blog():</code></div> <div class="line number7 index6 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">render_template(</code><code class="python string">'blog.html'</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Note how we have used the <strong>@login_required</strong> decorator. The <strong>blog.html</strong> template would be:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_158467" class="syntaxhighlighter nogutter xml"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="xml plain"><</code><code class="xml keyword">h2</code><code class="xml plain">>Welcome to the Blog</</code><code class="xml keyword">h2</code><code class="xml plain">></code></div> <div class="line number2 index1 alt1"> </div> <div class="line number3 index2 alt2"><code class="xml plain"><</code><code class="xml keyword">h3</code><code class="xml plain">>Hi {{ current_user.username }}</</code><code class="xml keyword">h3</code><code class="xml plain">></code></div> <div class="line number4 index3 alt1"> </div> <div class="line number5 index4 alt2"><code class="xml plain"><</code><code class="xml keyword">a</code> <code class="xml color1">href</code><code class="xml plain">=</code><code class="xml string">"{{ url_for('logout')}}"</code><code class="xml plain">>Logout Here</</code><code class="xml keyword">a</code><code class="xml plain">></code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Do checkout our <a class="rank-math-link" href="https://www.askpython.com/python-modules/flask/flask-templates"><span class="_ap_link_preview" data-preview-variation="relatedPostsPage" data-attribute="Flask Templates" data-url="https://www.askpython.com/python-modules/flask/flask-templates">Flask Templates</span></a> article to know more about Templates.</p> <h3>2.3 Coding the Log-in View</h3> <p>The Login view would be simple. It should do the following:</p> <ul> <li>If the user already authenticated, redirect to the blogs page or else display an HTML Form</li> <li>Retrieve the user information from the DB</li> <li>Compare the credentials, if correct, redirect to the blogs page</li> </ul> <p>So add the code:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_436406" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask, request, render_template</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">flask_login </code><code class="python keyword">import</code> <code class="python plain">current_user, login_user</code></div> <div class="line number3 index2 alt2"> </div> <div class="line number4 index3 alt1"><code class="python decorator">@app</code><code class="python plain">.route(</code><code class="python string">'/login'</code><code class="python plain">, methods </code><code class="python keyword">=</code> <code class="python plain">[</code><code class="python string">'POST'</code><code class="python plain">, </code><code class="python string">'GET'</code><code class="python plain">])</code></div> <div class="line number5 index4 alt2"><code class="python keyword">def</code> <code class="python plain">login():</code></div> <div class="line number6 index5 alt1"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">current_user.is_authenticated:</code></div> <div class="line number7 index6 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">redirect(</code><code class="python string">'/blogs'</code><code class="python plain">)</code></div> <div class="line number8 index7 alt1"><code class="python spaces"> </code> </div> <div class="line number9 index8 alt2"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">request.method </code><code class="python keyword">=</code><code class="python keyword">=</code> <code class="python string">'POST'</code><code class="python plain">:</code></div> <div class="line number10 index9 alt1"><code class="python spaces"> </code><code class="python plain">email </code><code class="python keyword">=</code> <code class="python plain">request.form[</code><code class="python string">'email'</code><code class="python plain">]</code></div> <div class="line number11 index10 alt2"><code class="python spaces"> </code><code class="python plain">user </code><code class="python keyword">=</code> <code class="python plain">UserModel.query.filter_by(email </code><code class="python keyword">=</code> <code class="python plain">email).first()</code></div> <div class="line number12 index11 alt1"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">user </code><code class="python keyword">is</code> <code class="python keyword">not</code> <code class="python color1">None</code> <code class="python keyword">and</code> <code class="python plain">user.check_password(request.form[</code><code class="python string">'password'</code><code class="python plain">]):</code></div> <div class="line number13 index12 alt2"><code class="python spaces"> </code><code class="python plain">login_user(user)</code></div> <div class="line number14 index13 alt1"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">redirect(</code><code class="python string">'/blogs'</code><code class="python plain">)</code></div> <div class="line number15 index14 alt2"><code class="python spaces"> </code> </div> <div class="line number16 index15 alt1"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">render_template(</code><code class="python string">'login.html'</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>And the <strong>login.html</strong> template:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_427559" class="syntaxhighlighter nogutter xml"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="xml plain"><</code><code class="xml keyword">form</code> <code class="xml color1">action</code><code class="xml plain">=</code><code class="xml string">""</code> <code class="xml color1">method</code> <code class="xml plain">= </code><code class="xml string">"POST"</code><code class="xml plain">></code></div> <div class="line number2 index1 alt1"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">p</code><code class="xml plain">>email <</code><code class="xml keyword">input</code> <code class="xml color1">type</code> <code class="xml plain">= </code><code class="xml string">"email"</code> <code class="xml color1">name</code> <code class="xml plain">= </code><code class="xml string">"email"</code> <code class="xml plain">/></</code><code class="xml keyword">p</code><code class="xml plain">></code></div> <div class="line number3 index2 alt2"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">p</code><code class="xml plain">>password <</code><code class="xml keyword">input</code> <code class="xml color1">type</code> <code class="xml plain">= </code><code class="xml string">"password"</code> <code class="xml color1">name</code> <code class="xml plain">= </code><code class="xml string">"password"</code> <code class="xml plain">/></</code><code class="xml keyword">p</code><code class="xml plain">></code></div> <div class="line number4 index3 alt1"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">p</code><code class="xml plain">> submit <</code><code class="xml keyword">input</code> <code class="xml color1">type</code> <code class="xml plain">= </code><code class="xml string">"submit"</code> <code class="xml color1">value</code> <code class="xml plain">= </code><code class="xml string">"Submit"</code> <code class="xml plain">/></</code><code class="xml keyword">p</code><code class="xml plain">></code></div> <div class="line number5 index4 alt2"><code class="xml plain"></</code><code class="xml keyword">form</code><code class="xml plain">></code></div> <div class="line number6 index5 alt1"> </div> <div class="line number7 index6 alt2"><code class="xml plain"><</code><code class="xml keyword">h3</code><code class="xml plain">>Dont Have an account??</</code><code class="xml keyword">h3</code><code class="xml plain">></code></div> <div class="line number8 index7 alt1"><code class="xml plain"><</code><code class="xml keyword">h3</code><code class="xml plain">><</code><code class="xml keyword">a</code> <code class="xml color1">href</code> <code class="xml plain">= </code><code class="xml string">"{{url_for('register') }}"</code><code class="xml plain">>Register Here</</code><code class="xml keyword">a</code><code class="xml plain">></</code><code class="xml keyword">h3</code><code class="xml plain">></code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <h3>2.4 Coding the Register View</h3> <p>The Register View should be able to do the following:</p> <ul> <li>if the user already authenticated, redirect to the blogs page or else display an HTML Form</li> <li>Add the user data to the DB</li> <li>Redirect to the login page</li> </ul> <p>So the code will be:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_31895" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask, request, render_template</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">flask_login </code><code class="python keyword">import</code> <code class="python plain">current_user</code></div> <div class="line number3 index2 alt2"> </div> <div class="line number4 index3 alt1"><code class="python decorator">@app</code><code class="python plain">.route(</code><code class="python string">'/register'</code><code class="python plain">, methods</code><code class="python keyword">=</code><code class="python plain">[</code><code class="python string">'POST'</code><code class="python plain">, </code><code class="python string">'GET'</code><code class="python plain">])</code></div> <div class="line number5 index4 alt2"><code class="python keyword">def</code> <code class="python plain">register():</code></div> <div class="line number6 index5 alt1"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">current_user.is_authenticated:</code></div> <div class="line number7 index6 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">redirect(</code><code class="python string">'/blogs'</code><code class="python plain">)</code></div> <div class="line number8 index7 alt1"><code class="python spaces"> </code> </div> <div class="line number9 index8 alt2"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">request.method </code><code class="python keyword">=</code><code class="python keyword">=</code> <code class="python string">'POST'</code><code class="python plain">:</code></div> <div class="line number10 index9 alt1"><code class="python spaces"> </code><code class="python plain">email </code><code class="python keyword">=</code> <code class="python plain">request.form[</code><code class="python string">'email'</code><code class="python plain">]</code></div> <div class="line number11 index10 alt2"><code class="python spaces"> </code><code class="python plain">username </code><code class="python keyword">=</code> <code class="python plain">request.form[</code><code class="python string">'username'</code><code class="python plain">]</code></div> <div class="line number12 index11 alt1"><code class="python spaces"> </code><code class="python plain">password </code><code class="python keyword">=</code> <code class="python plain">request.form[</code><code class="python string">'password'</code><code class="python plain">]</code></div> <div class="line number13 index12 alt2"> </div> <div class="line number14 index13 alt1"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">UserModel.query.filter_by(email</code><code class="python keyword">=</code><code class="python plain">email):</code></div> <div class="line number15 index14 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">(</code><code class="python string">'Email already Present'</code><code class="python plain">)</code></div> <div class="line number16 index15 alt1"><code class="python spaces"> </code> </div> <div class="line number17 index16 alt2"><code class="python spaces"> </code><code class="python plain">user </code><code class="python keyword">=</code> <code class="python plain">UserModel(email</code><code class="python keyword">=</code><code class="python plain">email, username</code><code class="python keyword">=</code><code class="python plain">username)</code></div> <div class="line number18 index17 alt1"><code class="python spaces"> </code><code class="python plain">user.set_password(password)</code></div> <div class="line number19 index18 alt2"><code class="python spaces"> </code><code class="python plain">db.session.add(user)</code></div> <div class="line number20 index19 alt1"><code class="python spaces"> </code><code class="python plain">db.session.commit()</code></div> <div class="line number21 index20 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">redirect(</code><code class="python string">'/login'</code><code class="python plain">)</code></div> <div class="line number22 index21 alt1"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">render_template(</code><code class="python string">'register.html'</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>Therefore the <strong>register.html</strong> page will be:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_958788" class="syntaxhighlighter nogutter xml"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="xml plain"><</code><code class="xml keyword">form</code> <code class="xml color1">action</code><code class="xml plain">=</code><code class="xml string">""</code> <code class="xml color1">method</code> <code class="xml plain">= </code><code class="xml string">"POST"</code><code class="xml plain">></code></div> <div class="line number2 index1 alt1"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">p</code><code class="xml plain">>email <</code><code class="xml keyword">input</code> <code class="xml color1">type</code> <code class="xml plain">= </code><code class="xml string">"email"</code> <code class="xml color1">name</code> <code class="xml plain">= </code><code class="xml string">"email"</code> <code class="xml plain">/></</code><code class="xml keyword">p</code><code class="xml plain">></code></div> <div class="line number3 index2 alt2"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">p</code><code class="xml plain">>Username <</code><code class="xml keyword">input</code> <code class="xml color1">type</code> <code class="xml plain">= </code><code class="xml string">"text"</code> <code class="xml color1">name</code> <code class="xml plain">= </code><code class="xml string">"username"</code> <code class="xml plain">/></</code><code class="xml keyword">p</code><code class="xml plain">></code></div> <div class="line number4 index3 alt1"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">p</code><code class="xml plain">>password <</code><code class="xml keyword">input</code> <code class="xml color1">type</code> <code class="xml plain">= </code><code class="xml string">"password"</code> <code class="xml color1">name</code> <code class="xml plain">= </code><code class="xml string">"password"</code> <code class="xml plain">/></</code><code class="xml keyword">p</code><code class="xml plain">></code></div> <div class="line number5 index4 alt2"><code class="xml spaces"> </code><code class="xml plain"><</code><code class="xml keyword">p</code><code class="xml plain">> submit <</code><code class="xml keyword">input</code> <code class="xml color1">type</code> <code class="xml plain">= </code><code class="xml string">"submit"</code> <code class="xml color1">value</code> <code class="xml plain">= </code><code class="xml string">"Submit"</code> <code class="xml plain">/></</code><code class="xml keyword">p</code><code class="xml plain">></code></div> <div class="line number6 index5 alt1"><code class="xml plain"></</code><code class="xml keyword">form</code><code class="xml plain">></code></div> <div class="line number7 index6 alt2"> </div> <div class="line number8 index7 alt1"><code class="xml plain"><</code><code class="xml keyword">h3</code><code class="xml plain">>Already Have an Account?</</code><code class="xml keyword">h3</code><code class="xml plain">><</code><code class="xml keyword">br</code><code class="xml plain">></code></div> <div class="line number9 index8 alt2"><code class="xml plain"><</code><code class="xml keyword">h3</code><code class="xml plain">><</code><code class="xml keyword">a</code> <code class="xml color1">href</code> <code class="xml plain">=</code><code class="xml string">"{{url_for('login')}}"</code><code class="xml plain">>Login Here</</code><code class="xml keyword">a</code><code class="xml plain">></</code><code class="xml keyword">h3</code><code class="xml plain">></code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <h3>2.5 Coding the Logout View</h3> <p>The Logout View should simply log users out. Therefore add the code:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_46417" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask, render_template</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">Flask_login </code><code class="python keyword">import</code> <code class="python plain">logout_user</code></div> <div class="line number3 index2 alt2"> </div> <div class="line number4 index3 alt1"><code class="python decorator">@app</code><code class="python plain">.route(</code><code class="python string">'/logout'</code><code class="python plain">)</code></div> <div class="line number5 index4 alt2"><code class="python keyword">def</code> <code class="python plain">logout():</code></div> <div class="line number6 index5 alt1"><code class="python spaces"> </code><code class="python plain">logout_user()</code></div> <div class="line number7 index6 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">redirect(</code><code class="python string">'/blogs'</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>That’s it !! Therefore let us once look at the full code for this section:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_180034" class="syntaxhighlighter nogutter python"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="python keyword">from</code> <code class="python plain">flask </code><code class="python keyword">import</code> <code class="python plain">Flask,render_template,request,redirect</code></div> <div class="line number2 index1 alt1"><code class="python keyword">from</code> <code class="python plain">flask_login </code><code class="python keyword">import</code> <code class="python plain">login_required, current_user, login_user, logout_user</code></div> <div class="line number3 index2 alt2"><code class="python keyword">from</code> <code class="python plain">models </code><code class="python keyword">import</code> <code class="python plain">UserModel,db,login</code></div> <div class="line number4 index3 alt1"> </div> <div class="line number5 index4 alt2"><code class="python plain">app </code><code class="python keyword">=</code> <code class="python plain">Flask(__name__)</code></div> <div class="line number6 index5 alt1"><code class="python plain">app.secret_key </code><code class="python keyword">=</code> <code class="python string">'xyz'</code></div> <div class="line number7 index6 alt2"> </div> <div class="line number8 index7 alt1"><code class="python plain">app.config[</code><code class="python string">'SQLALCHEMY_DATABASE_URI'</code><code class="python plain">] </code><code class="python keyword">=</code> <code class="python string">'sqlite:///data.db'</code></div> <div class="line number9 index8 alt2"><code class="python plain">app.config[</code><code class="python string">'SQLALCHEMY_TRACK_MODIFICATIONS'</code><code class="python plain">] </code><code class="python keyword">=</code> <code class="python color1">False</code></div> <div class="line number10 index9 alt1"> </div> <div class="line number11 index10 alt2"> </div> <div class="line number12 index11 alt1"><code class="python plain">db.init_app(app)</code></div> <div class="line number13 index12 alt2"><code class="python plain">login.init_app(app)</code></div> <div class="line number14 index13 alt1"><code class="python plain">login.login_view </code><code class="python keyword">=</code> <code class="python string">'login'</code></div> <div class="line number15 index14 alt2"> </div> <div class="line number16 index15 alt1"><code class="python decorator">@app</code><code class="python plain">.before_first_request</code></div> <div class="line number17 index16 alt2"><code class="python keyword">def</code> <code class="python plain">create_all():</code></div> <div class="line number18 index17 alt1"><code class="python spaces"> </code><code class="python plain">db.create_all()</code></div> <div class="line number19 index18 alt2"><code class="python spaces"> </code> </div> <div class="line number20 index19 alt1"><code class="python decorator">@app</code><code class="python plain">.route(</code><code class="python string">'/blogs'</code><code class="python plain">)</code></div> <div class="line number21 index20 alt2"><code class="python decorator">@login_required</code></div> <div class="line number22 index21 alt1"><code class="python keyword">def</code> <code class="python plain">blog():</code></div> <div class="line number23 index22 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">render_template(</code><code class="python string">'blog.html'</code><code class="python plain">)</code></div> <div class="line number24 index23 alt1"> </div> <div class="line number25 index24 alt2"> </div> <div class="line number26 index25 alt1"><code class="python decorator">@app</code><code class="python plain">.route(</code><code class="python string">'/login'</code><code class="python plain">, methods </code><code class="python keyword">=</code> <code class="python plain">[</code><code class="python string">'POST'</code><code class="python plain">, </code><code class="python string">'GET'</code><code class="python plain">])</code></div> <div class="line number27 index26 alt2"><code class="python keyword">def</code> <code class="python plain">login():</code></div> <div class="line number28 index27 alt1"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">current_user.is_authenticated:</code></div> <div class="line number29 index28 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">redirect(</code><code class="python string">'/blogs'</code><code class="python plain">)</code></div> <div class="line number30 index29 alt1"><code class="python spaces"> </code> </div> <div class="line number31 index30 alt2"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">request.method </code><code class="python keyword">=</code><code class="python keyword">=</code> <code class="python string">'POST'</code><code class="python plain">:</code></div> <div class="line number32 index31 alt1"><code class="python spaces"> </code><code class="python plain">email </code><code class="python keyword">=</code> <code class="python plain">request.form[</code><code class="python string">'email'</code><code class="python plain">]</code></div> <div class="line number33 index32 alt2"><code class="python spaces"> </code><code class="python plain">user </code><code class="python keyword">=</code> <code class="python plain">UserModel.query.filter_by(email </code><code class="python keyword">=</code> <code class="python plain">email).first()</code></div> <div class="line number34 index33 alt1"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">user </code><code class="python keyword">is</code> <code class="python keyword">not</code> <code class="python color1">None</code> <code class="python keyword">and</code> <code class="python plain">user.check_password(request.form[</code><code class="python string">'password'</code><code class="python plain">]):</code></div> <div class="line number35 index34 alt2"><code class="python spaces"> </code><code class="python plain">login_user(user)</code></div> <div class="line number36 index35 alt1"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">redirect(</code><code class="python string">'/blogs'</code><code class="python plain">)</code></div> <div class="line number37 index36 alt2"><code class="python spaces"> </code> </div> <div class="line number38 index37 alt1"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">render_template(</code><code class="python string">'login.html'</code><code class="python plain">)</code></div> <div class="line number39 index38 alt2"> </div> <div class="line number40 index39 alt1"><code class="python decorator">@app</code><code class="python plain">.route(</code><code class="python string">'/register'</code><code class="python plain">, methods</code><code class="python keyword">=</code><code class="python plain">[</code><code class="python string">'POST'</code><code class="python plain">, </code><code class="python string">'GET'</code><code class="python plain">])</code></div> <div class="line number41 index40 alt2"><code class="python keyword">def</code> <code class="python plain">register():</code></div> <div class="line number42 index41 alt1"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">current_user.is_authenticated:</code></div> <div class="line number43 index42 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">redirect(</code><code class="python string">'/blogs'</code><code class="python plain">)</code></div> <div class="line number44 index43 alt1"><code class="python spaces"> </code> </div> <div class="line number45 index44 alt2"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">request.method </code><code class="python keyword">=</code><code class="python keyword">=</code> <code class="python string">'POST'</code><code class="python plain">:</code></div> <div class="line number46 index45 alt1"><code class="python spaces"> </code><code class="python plain">email </code><code class="python keyword">=</code> <code class="python plain">request.form[</code><code class="python string">'email'</code><code class="python plain">]</code></div> <div class="line number47 index46 alt2"><code class="python spaces"> </code><code class="python plain">username </code><code class="python keyword">=</code> <code class="python plain">request.form[</code><code class="python string">'username'</code><code class="python plain">]</code></div> <div class="line number48 index47 alt1"><code class="python spaces"> </code><code class="python plain">password </code><code class="python keyword">=</code> <code class="python plain">request.form[</code><code class="python string">'password'</code><code class="python plain">]</code></div> <div class="line number49 index48 alt2"> </div> <div class="line number50 index49 alt1"><code class="python spaces"> </code><code class="python keyword">if</code> <code class="python plain">UserModel.query.filter_by(email</code><code class="python keyword">=</code><code class="python plain">email).first():</code></div> <div class="line number51 index50 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">(</code><code class="python string">'Email already Present'</code><code class="python plain">)</code></div> <div class="line number52 index51 alt1"><code class="python spaces"> </code> </div> <div class="line number53 index52 alt2"><code class="python spaces"> </code><code class="python plain">user </code><code class="python keyword">=</code> <code class="python plain">UserModel(email</code><code class="python keyword">=</code><code class="python plain">email, username</code><code class="python keyword">=</code><code class="python plain">username)</code></div> <div class="line number54 index53 alt1"><code class="python spaces"> </code><code class="python plain">user.set_password(password)</code></div> <div class="line number55 index54 alt2"><code class="python spaces"> </code><code class="python plain">db.session.add(user)</code></div> <div class="line number56 index55 alt1"><code class="python spaces"> </code><code class="python plain">db.session.commit()</code></div> <div class="line number57 index56 alt2"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">redirect(</code><code class="python string">'/login'</code><code class="python plain">)</code></div> <div class="line number58 index57 alt1"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">render_template(</code><code class="python string">'register.html'</code><code class="python plain">)</code></div> <div class="line number59 index58 alt2"> </div> <div class="line number60 index59 alt1"> </div> <div class="line number61 index60 alt2"><code class="python decorator">@app</code><code class="python plain">.route(</code><code class="python string">'/logout'</code><code class="python plain">)</code></div> <div class="line number62 index61 alt1"><code class="python keyword">def</code> <code class="python plain">logout():</code></div> <div class="line number63 index62 alt2"><code class="python spaces"> </code><code class="python plain">logout_user()</code></div> <div class="line number64 index63 alt1"><code class="python spaces"> </code><code class="python keyword">return</code> <code class="python plain">redirect(</code><code class="python string">'/blogs'</code><code class="python plain">)</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>The <strong>UserModel.query.filter_by(email=email).first() </strong>will return the firt User it gets from the Database or will return <strong>None</strong> if no user was found.</p> <h2><strong>Implementation</strong> of the Flask User Authentication Application</h2> <p>Let us finally test our app. Run the Flask file:</p> <div class="wp-block-syntaxhighlighter-code "> <div> <div id="highlighter_388971" class="syntaxhighlighter nogutter bash"> <table border="0" cellspacing="0" cellpadding="0"> <tbody> <tr> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"><code class="bash plain">python filename.py</code></div> </div> </td> </tr> </tbody> </table> </div> </div> </div> <p>And try to go to “<strong>/blogs</strong>“. You will get redirected to the <strong>login </strong>page.</p> <div class="wp-block-image"> <figure class="aligncenter size-large"><img class="wp-image-8962 entered litespeed-loaded" src="https://www.askpython.com/wp-content/uploads/2020/09/login-2.png.webp" sizes="(max-width: 798px) 100vw, 798px" srcset="https://www.askpython.com/wp-content/uploads/2020/09/login-2.png.webp 798w, https://www.askpython.com/wp-content/uploads/2020/09/login-2-300x143.png.webp 300w, https://www.askpython.com/wp-content/uploads/2020/09/login-2-768x367.png.webp 768w" alt="Login " width="798" height="381" data-lazyloaded="1" data-src="https://www.askpython.com/wp-content/uploads/2020/09/login-2.png.webp" data-srcset="https://www.askpython.com/wp-content/uploads/2020/09/login-2.png.webp 798w, https://www.askpython.com/wp-content/uploads/2020/09/login-2-300x143.png.webp 300w, https://www.askpython.com/wp-content/uploads/2020/09/login-2-768x367.png.webp 768w" data-sizes="(max-width: 798px) 100vw, 798px" data-ll-status="loaded" /> <figcaption>Login</figcaption> </figure> </div> <p>Click on register and then add your details.</p> <div class="wp-block-image"> <figure class="aligncenter size-large"><img class="wp-image-8963 entered litespeed-loaded" src="https://www.askpython.com/wp-content/uploads/2020/09/register.png.webp" sizes="(max-width: 798px) 100vw, 798px" srcset="https://www.askpython.com/wp-content/uploads/2020/09/register.png.webp 798w, https://www.askpython.com/wp-content/uploads/2020/09/register-300x143.png.webp 300w, https://www.askpython.com/wp-content/uploads/2020/09/register-768x367.png.webp 768w" alt="Register" width="798" height="381" data-lazyloaded="1" data-src="https://www.askpython.com/wp-content/uploads/2020/09/register.png.webp" data-srcset="https://www.askpython.com/wp-content/uploads/2020/09/register.png.webp 798w, https://www.askpython.com/wp-content/uploads/2020/09/register-300x143.png.webp 300w, https://www.askpython.com/wp-content/uploads/2020/09/register-768x367.png.webp 768w" data-sizes="(max-width: 798px) 100vw, 798px" data-ll-status="loaded" /> <figcaption>Register</figcaption> </figure> </div> <p>Hit submit, you will reach back the login page. This time enter you credentials and log in. You will see the Blogs page !!</p> <div class="wp-block-image"> <figure class="aligncenter size-large"><img class="wp-image-8964 entered litespeed-loaded" src="https://www.askpython.com/wp-content/uploads/2020/09/blogs.png.webp" sizes="(max-width: 627px) 100vw, 627px" srcset="https://www.askpython.com/wp-content/uploads/2020/09/blogs.png.webp 627w, https://www.askpython.com/wp-content/uploads/2020/09/blogs-300x132.png.webp 300w" alt="Blogs" width="627" height="275" data-lazyloaded="1" data-src="https://www.askpython.com/wp-content/uploads/2020/09/blogs.png.webp" data-srcset="https://www.askpython.com/wp-content/uploads/2020/09/blogs.png.webp 627w, https://www.askpython.com/wp-content/uploads/2020/09/blogs-300x132.png.webp 300w" data-sizes="(max-width: 627px) 100vw, 627px" data-ll-status="loaded" /> <figcaption>Blogs</figcaption> </figure> </div> <p><strong>Note:</strong> Using simple emails like <strong>a@gmail.com</strong> might give you a error like the one shown below in the Chrome Browser.</p> <div class="wp-block-image"> <figure class="aligncenter size-large"><img class="wp-image-9015 entered litespeed-loaded" src="https://www.askpython.com/wp-content/uploads/2020/09/Redirect-to-blog-successful-login.png.webp" sizes="(max-width: 627px) 100vw, 627px" srcset="https://www.askpython.com/wp-content/uploads/2020/09/Redirect-to-blog-successful-login.png.webp 627w, https://www.askpython.com/wp-content/uploads/2020/09/Redirect-to-blog-successful-login-300x125.png.webp 300w" alt="Redirect To Blog Successful Login" width="627" height="262" data-lazyloaded="1" data-src="https://www.askpython.com/wp-content/uploads/2020/09/Redirect-to-blog-successful-login.png.webp" data-srcset="https://www.askpython.com/wp-content/uploads/2020/09/Redirect-to-blog-successful-login.png.webp 627w, https://www.askpython.com/wp-content/uploads/2020/09/Redirect-to-blog-successful-login-300x125.png.webp 300w" data-sizes="(max-width: 627px) 100vw, 627px" data-ll-status="loaded" /> <figcaption>Redirect To Blog Successful Login</figcaption> </figure> </div> <p>As you can see, we have been redirected to the “blogs” endpoint here. There’s a security message that popped up in my screenshot above since I’ve used a random non-existent with a very weak password.</p> <p>You can try the same with a stronger password and a good email address and you’ll directly see the blogs page instead of the security warning as it is in this case.</p> <div class="code-block code-block-3"> <div id="00000001-414a4cf5-0eaf-4380-a6dc-f9a2adc715f9" class="_ap_apex_ad" data-section="00000001-414a4cf5-0eaf-4380-a6dc-f9a2adc715f9" data-orig-id="03dec052-3fc4-4753-88e1-b2bb64738009" data-render-time="1668991059753" data-ap-network="adpTags" data-refresh-time="1669046202046" data-timeout="197888"> <div id="ADP_41988_responsivexresponsive_00000001-414a4cf5-0eaf-4380-a6dc-f9a2adc715f9"></div> <div id="common-container-ADP_41988_responsivexresponsive_00000001-414a4cf5-0eaf-4380-a6dc-f9a2adc715f9" class="poweredByAdPushupCommonContainer"><strong>Conclusion</strong></div> </div> </div> <p>That’s it, guys! This was all about User Authentication in Flask. Do check out our <a class="rank-math-link" href="https://www.askpython.com/python-modules/flask/flask-sessions"><span class="_ap_link_preview" data-preview-variation="relatedPostsPage" data-attribute="Flask sessions" data-url="https://www.askpython.com/python-modules/flask/flask-sessions">Flask sessions</span></a> and <a class="rank-math-link" href="https://www.askpython.com/python-modules/flask/flask-cookies"><span class="_ap_link_preview" data-preview-variation="relatedPostsPage" data-attribute="cookies" data-url="https://www.askpython.com/python-modules/flask/flask-cookies">cookies</span></a> article to know more about how they work.</p> <p>In the next article we will deploy our application onto a Cloud server.</p> <div class="code-block code-block-11"> <div id="00000001-3f83d8dc-b3ce-4629-bb92-0cfb59a49f46" class="_ap_apex_ad" data-section="00000001-3f83d8dc-b3ce-4629-bb92-0cfb59a49f46" data-orig-id="0e1e4ba3-efe2-4fac-9c17-74175ab50b3e" data-render-time="1668991059756" data-ap-network="adpTags" data-refresh-time="1669046193954" data-timeout="197261"> <div id="ADP_41988_responsivexresponsive_00000001-3f83d8dc-b3ce-4629-bb92-0cfb59a49f46" data-google-query-id="CJHWxc3Rv_sCFVBJDwId75QBPA"></div> </div> </div> </div>
Comments (25)
Leave a Comment
wNEaZAECDxFEQwMCc
LriNuPRqnggjFzhJOTJj
hPUpBwhzWOVmqtHFRQJd
vMaZRQDqxxMwpmLlw
FAWTWsgIINtkZtmOVqYnjq
jyxAvavmiHVQsLwFTho
aDiqyzhREDVUmsNiGKfHdBqh
nzjgyliszqfrzjxvvkfdjxlkmlvfly
KBJQcyIMhxdAYyDwnzTRhXgM
PsqenfAeqEGAuQEbnirgXcs
wAEercEEZmVNiCypDEf
wAEercEEZmVNiCypDEf
wAEercEEZmVNiCypDEf
EJSKkZqjrLZFBQosPO
CoFHnXKPOcVwZaZCgvODA
qfhijphvhjimzvdxlkelwjxhghlwxn
orkvqvwdvnxmgkxhojqxzyfhlhvzln
gfpmnkdhgymktxqjpivgxmqynmxlun
aXwpIbYrqPfYxRjcDSUtNw
cljkLpSfuDIzOdoVEO
JKEKHdnebDDzQhcWgwnbQtXE
OEDxbqTNBTqxkSQtgDm
DtzziLKUVdRnorJnVrJEnYd
BxKOVYWqOJMiCTEYHbSlpFD
ZQuNIzCoolTDscWjE