{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/9","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"11 Tips for Managing Remote Software Engineering Teams The software developer role is among the top 5 remote-oriented jobs in the world…","fields":{"slug":"/engineering/guest-post/tips-for-managing-remote-software-engineering-teams/"},"html":"<h1 id=\"11-tips-for-managing-remote-software-engineering-teams\" style=\"position:relative;\"><a href=\"#11-tips-for-managing-remote-software-engineering-teams\" aria-label=\"11 tips for managing remote software engineering teams permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>11 Tips for Managing Remote Software Engineering Teams</h1>\n<p>The software developer role is among the top 5 remote-oriented jobs in the world. After the pandemic, <a href=\"https://www.apollotechnical.com/statistics-on-remote-workers/\">92% of people</a> expect to work at least 1 day per week from home, and 80% expect to work at least 3 days from home. Accordingly, fostering an environment and working conditions for software engineers to work remotely is inevitable. In fact, <a href=\"https://terminal.io/state-of-remote-engineering-2021\">75% of engineers</a> want to work remotely, primary reasons being the lack of an annoying commute and a better work-life balance .</p>\n<p>If companies fail to create an effective remote working environment, their developers will eventually find another employer who can meet their needs to work remotely effectively.</p>\n<p>This article will give you 11 tips for managing remote software engineering teams, so you can adjust and improve your hiring, communication, and your team's collective output.</p>\n<h2 id=\"why-hire-remote-developers\" style=\"position:relative;\"><a href=\"#why-hire-remote-developers\" aria-label=\"why hire remote developers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why Hire Remote Developers?</h2>\n<p>The first and most obvious reason to hire remote developers is that your addressable talent pool is global . Utilizing a <a href=\"https://recruitcrm.io/blogs/hiring-platform/\">recruitment platform</a> allows you to tap into a vast array of talent options. It's actually a good thing you don't have to deal with visas and relocation packages.</p>\n<p>Another reason is that many good developers are already in remote jobs. They have become used to a certain remote lifestyle and likely won't change that. As an employer, you must adapt to the growing market of digital nomads.</p>\n<h2 id=\"what-are-the-challenges-in-managing-remote-teams\" style=\"position:relative;\"><a href=\"#what-are-the-challenges-in-managing-remote-teams\" aria-label=\"what are the challenges in managing remote teams permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What are the Challenges in Managing Remote Teams?</h2>\n<p>Probably the biggest challenge with managing remote teams is asynchronous communication or a complete lack of communication. This can cause delays, duplicate work, or even wrong requirements being implemented in the product.</p>\n<p>In an attempt to counter that, developers sometimes change their working schedules to have a bigger time overlap with their team members. However, this can easily lead to irregular working schedules and overworking.</p>\n<h2 id=\"tips-on-how-to-manage-a-remote-software-developer-team\" style=\"position:relative;\"><a href=\"#tips-on-how-to-manage-a-remote-software-developer-team\" aria-label=\"tips on how to manage a remote software developer team permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Tips on How to Manage a Remote Software Developer Team</h2>\n<p>Luckily, you can surmount all these challenges by establishing some rules for the team. Stand-up meetings are a widely practiced SCRUM ceremony and have proven to be a very effective communication method.</p>\n<p>It's also a good idea to hire developers who actually have worked in remote roles since they likely have more experience of self-management and are more goal-oriented than work-hours oriented.</p>\n<p>Trust in the team, frequent communication, and feedback make a huge difference. Next, we're looking at 11 specific tips that you can implement to foster a more effective remote working culture within your software development team.</p>\n<h2 id=\"1-stand-up-meetings-and-scheduled-communication\" style=\"position:relative;\"><a href=\"#1-stand-up-meetings-and-scheduled-communication\" aria-label=\"1 stand up meetings and scheduled communication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. Stand-up Meetings and Scheduled Communication</h2>\n<p>Establish a stand-up meeting time and make sure to include all team members . Since the team is fully remote, you have to utilize video conferencing or text chat software like Slack to hold a stand-up meeting. This will allow for quick feedback loops on your progress throughout the day while also providing valuable face-to-face interaction with remote employees. A well-run stand-up meeting should take no more than 15 minutes so that participants can still get their work done afterward.</p>\n<p>Schedule regular communication times during which people can discuss ideas, decisions, and general feelings about what is happening inside of your organization; this could be as small as one hour per week or as frequent as daily depending on what kind of information needs to flow between team members.</p>\n<p>However, be cautious of video fatigue. The <a href=\"https://solitaired.com/Improving-remote-work\">team at Solitaired</a> improved their development team output and speed by moving their stand-up meetings to a written format. In the video meetings they had, they started writing email summaries and clearly outlining responsibilities.</p>\n<h2 id=\"2-over-communication-is-crucial-for-remote-teams\" style=\"position:relative;\"><a href=\"#2-over-communication-is-crucial-for-remote-teams\" aria-label=\"2 over communication is crucial for remote teams permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Over-communication is Crucial for Remote Teams</h2>\n<p>One tip for managing remote software development teams is to \"over-communicate.\" What does this mean? Don't just communicate as little as you can, which can create a feeling of insecurity among team members. Communication is critical when <a href=\"https://www.loginradius.com/blog/fuel/tips-managing-remote-team/\">managing a remote team</a> because you don't have the same level of informal rapport as in face-to-face interactions.</p>\n<p>Another thing you can do is send follow-up emails after <a href=\"https://callhippo.com/blog/business/increase-your-employees-productivity-with-remote-working-and-voip\">VoIP phone</a> calls. This helps to ensure that all points are covered and that nobody has any unanswered questions.</p>\n<h2 id=\"3-time-zones-and-common-time-for-synchronous-conversations\" style=\"position:relative;\"><a href=\"#3-time-zones-and-common-time-for-synchronous-conversations\" aria-label=\"3 time zones and common time for synchronous conversations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Time Zones and \"Common Time\" for Synchronous Conversations</h2>\n<p>One of the biggest challenges is timezones. You need to decide whether you want a consistent \"common time\" or if it's acceptable for team members to work off-hours . The advantage of common time is that all team members are on at once and can have conversations in real-time , which means more collaboration and less miscommunication.</p>\n<h2 id=\"4-look-for-proof-of-self-management-when-hiring\" style=\"position:relative;\"><a href=\"#4-look-for-proof-of-self-management-when-hiring\" aria-label=\"4 look for proof of self management when hiring permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. Look for Proof of Self-Management When Hiring</h2>\n<p>One of the essential qualities to look for in a software engineer is self-management. You want somebody who can think critically and find solutions instead of being told what to do. Self-managers also can see through other people's advice and execute accordingly; they are not chained by following others' instructions blindly without understanding why they're doing it this way or that.</p>\n<h2 id=\"5-clear-onboarding-and-product-vision\" style=\"position:relative;\"><a href=\"#5-clear-onboarding-and-product-vision\" aria-label=\"5 clear onboarding and product vision permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5. Clear Onboarding and Product Vision</h2>\n<p>Straightforward onboarding and product vision is a necessity for remote teams. Clear communication about what the team will be working on, how they will work together, and their managers can help reduce confusion among teammates.</p>\n<p>By providing clear expectations of roles and responsibilities and establishing an understanding of company goals early on in the process (even as early as <a href=\"https://360learning.com/blog/online-employee-training/\">employee training</a>), you allow your new employees to hit the ground running with less stress.</p>\n<h2 id=\"6-goals-above-working-hours-goals-that-inspire-results\" style=\"position:relative;\"><a href=\"#6-goals-above-working-hours-goals-that-inspire-results\" aria-label=\"6 goals above working hours goals that inspire results permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>6. Goals Above Working Hours; Goals That Inspire Results</h2>\n<p>Goals are more important than the number of hours your team works. You will never get a team to work harder by working them more hours. You don't want your employees to feel like they're on a hamster wheel. Instead, you want your team to pursue goals that inspire results. This is important because research has shown that employees will work harder and report to be <a href=\"https://terminal.io/state-of-remote-engineering-2021\"> 46% more productive </a> when staff goals are aligned with organizational priorities.</p>\n<p>Make sure your team knows what they're working on: Communicate with your remote teams (or any team) so that everyone is clear about the objectives of their projects. Make a habit out of updating them regularly on progress made or obstacles encountered. This way, you'll avoid getting blindsided when someone emails asking for an update; instead, you can proactively provide updates as they happen.</p>\n<h2 id=\"7-tools-that-support-or-hinder-engineers\" style=\"position:relative;\"><a href=\"#7-tools-that-support-or-hinder-engineers\" aria-label=\"7 tools that support or hinder engineers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>7. Tools That Support or Hinder Engineers</h2>\n<p>Good tools are a must for remote software engineering teams. These tools should allow for instant messaging, time tracking, file sharing, and scheduling.</p>\n<p>A few in the list of great remote software engineering team tools are:</p>\n<ul>\n<li><strong>Slack</strong> – works well with external members as it has a chat room option</li>\n<li><strong>Google Drive</strong> – syncs files between devices, so you have access anywhere</li>\n<li><strong>Zoom</strong> – video conferencing, which is easy to use and scales with your team's needs; also offers screen sharing functionality when needed; probably the <a href=\"https://www.webinarsoftware.org/best-webinar-software/\">best webinar platform</a></li>\n</ul>\n<h2 id=\"8-invest-in-a-team-lead-and-celebrate-small-accomplishments\" style=\"position:relative;\"><a href=\"#8-invest-in-a-team-lead-and-celebrate-small-accomplishments\" aria-label=\"8 invest in a team lead and celebrate small accomplishments permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>8. Invest in a Team Lead and Celebrate Small Accomplishments</h2>\n<p>When managing a remote software engineering team, it is crucial to have an onsite person who can connect with the whole team. This person should be able to take over tasks when necessary and provide updates proactively. It will also be helpful for this lead engineer to help celebrate small accomplishments to keep morale high among team members who are far away from one another. One way could be giving rewards to team members who have gone the extra mile or finished a critical job in time. It's good for team morale to give praise publicly, in front of the entire team.</p>\n<h2 id=\"9-team-feedback-goes-a-long-way\" style=\"position:relative;\"><a href=\"#9-team-feedback-goes-a-long-way\" aria-label=\"9 team feedback goes a long way permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>9. Team Feedback Goes a Long Way</h2>\n<p>When managing a remote software engineering team, it is crucial to actively solicit feedback from the group. This will help build trust and understanding among team members. It can also prevent misunderstandings when regular staff members get back onsite or new hires arrive to understand their role within the company and expectations.</p>\n<h2 id=\"10-building-trust-with-remote-team-members\" style=\"position:relative;\"><a href=\"#10-building-trust-with-remote-team-members\" aria-label=\"10 building trust with remote team members permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>10. Building Trust With Remote Team Members</h2>\n<p>Since team members on a remote software engineering team lack in person interactions, it is vital to put emphasis on building trust with each other. This can be done through regular conference calls and short meetings for everyone to get acquainted with how they work together.</p>\n<p>Another way of building rapport is by providing online tools that allow team members to share thoughts or inputs and provide feedback and encourage self-management among employees who are not always on-site.</p>\n<h2 id=\"11-annual-get-togethers-even-if-everyone-cant-make-it\" style=\"position:relative;\"><a href=\"#11-annual-get-togethers-even-if-everyone-cant-make-it\" aria-label=\"11 annual get togethers even if everyone cant make it permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>11. Annual Get-Togethers, Even If Everyone Can't Make It</h2>\n<p>To be successful, remote software engineering teams need natural ways of building trust. This includes annual get-togethers for the team to mingle and socialize with one another in a casual setting to chat about their projects on an individual level. This is a great opportunity for team-building activities and events.</p>\n<h1 id=\"bonus-tip\" style=\"position:relative;\"><a href=\"#bonus-tip\" aria-label=\"bonus tip permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Bonus Tip</h1>\n<h2 id=\"team-one-on-one-communication\" style=\"position:relative;\"><a href=\"#team-one-on-one-communication\" aria-label=\"team one on one communication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Team One-on-One Communication</h2>\n<p>Team one-on-one communication is just essential as team cohesion. This allows your team members to talk about any difficulties, they're scared to bring up in group sessions. It's also a good moment to check in with team members about their role and whether it aligns with their overall career ambitions.</p>\n<h2 id=\"key-takeaways-for-managing-remote-software-engineering-teams\" style=\"position:relative;\"><a href=\"#key-takeaways-for-managing-remote-software-engineering-teams\" aria-label=\"key takeaways for managing remote software engineering teams permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Key Takeaways for Managing Remote Software Engineering Teams</h2>\n<p>Managing remote software engineering teams is a critical part of the equation for creating a positive impact in your company. The challenge with handling remote teams can be people, time, or budget constraints. By following these best practices for managing remote software development teams and by investing wisely in your team members' success, you can work through any obstacles you face on the journey to becoming more successful as a business owner or a team lead.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"July 26, 2021","updated_date":null,"description":"This article will give you 11 tips for managing remote software engineering teams, so you can adjust and improve your hiring, communication, and your team's collective output.","title":"11 Tips for Managing Remote Software Engineering Teams","tags":["Remote Work","Developer","Software Engineering"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.3333333333333333,"src":"/static/b56c12fcaad35ed98c69dce42a2cf52e/14b42/cover.jpg","srcSet":"/static/b56c12fcaad35ed98c69dce42a2cf52e/f836f/cover.jpg 200w,\n/static/b56c12fcaad35ed98c69dce42a2cf52e/2244e/cover.jpg 400w,\n/static/b56c12fcaad35ed98c69dce42a2cf52e/14b42/cover.jpg 800w,\n/static/b56c12fcaad35ed98c69dce42a2cf52e/47498/cover.jpg 1200w,\n/static/b56c12fcaad35ed98c69dce42a2cf52e/0e329/cover.jpg 1600w,\n/static/b56c12fcaad35ed98c69dce42a2cf52e/21d0b/cover.jpg 5184w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Erkki Muuga","github":null,"avatar":null}}}},{"node":{"excerpt":"It is scientifically proven that helping others makes people happy. Probably no one knows this better than the developer community around…","fields":{"slug":"/engineering/loginradius-sponsorship-freecodecamp/"},"html":"<p>It is scientifically proven that helping others makes people happy. Probably no one knows this better than the developer community around the world, which continues to amaze by contributing extensively to free and open source software.</p>\n<p>And there is <a href=\"https://www.freecodecamp.org/\">freeCodeCamp</a> community, a nonprofit started in 2014 by <a href=\"https://twitter.com/ossia\">Quincy Larson</a>. It has been helping thousands of aspiring developers learn web development and find their first software jobs. The community features a self-paced learning platform that helps learn various web technologies, including Bootstrap, D3, jQuery, and React, among many others.</p>\n<p>Being a nonprofit, freeCodeCamp entirely works based on charitable donations and contributions of developers to maintain its learning platform. In fact, it is so efficient that with every $5 in donation, it can provide more than 250 hours of learning. And it is so effective that some of its alumni work for marquee tech companies like Apple, Google, Microsoft, and Amazon, among others.</p>\n<p>In 2013, just a year before freeCodeCamp was established, we founded LoginRadius with a vision to secure every identity on this planet. From our early beginnings, we have developed LoginRadius CIAM to empower developers to build more secure applications and simplify the implementation of customer identity and access management on their production applications to save development and maintenance time. Today, burgeoning startups to Fortune 500 companies trust LoginRadius, and we're now collectively handling 1.17 billion user identities for our customers worldwide.</p>\n<p>We are as obsessed as freeCodeCamp to support and enable the developer community to do much more and make this world a better place. And we wanted to continuously help the freeCodeCamp community in any way possible.</p>\n<p>Today, we are a <a href=\"https://www.freecodecamp.org/news/sponsors/\">proud sponsor</a> of freeCodeCamp and supporting the community's developers. </p>\n<p><a href=\"https://accounts.loginradius.com/auth.aspx?action=register\">Signup here</a> if you're a developer from the freeCodeCamp community. And we'll offer $200 credits so you can leverage LoginRadius CIAM — beyond the free developer tier — to implement highly secure, user-centric customer identity and access management.</p>\n<p>This is indeed a moment of joy and pride for everyone at LoginRadius. We would like to extend our gratitude to freeCodeCamp for letting us be a part of its journey in strengthening the developer community.</p>\n<p>By the way, if you want to share your expertise with the developer community, please feel free to write for the LoginRadius Blog portal. We have an open for contributions policy so anyone around the world can <a href=\"https://github.com/LoginRadius/engineering-portal/blob/master/CONTRIBUTING.md\">contribute</a>. Find more details on our public <a href=\"https://github.com/LoginRadius/engineering-portal\">GitHub repo</a>.</p>\n<p><img src=\"https://media.giphy.com/media/xUPGcGJJMFeAPhqrfi/giphy.gif\" alt=\"Squad Goals\"></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"July 16, 2021","updated_date":null,"description":"LoginRadius now supports the freeCodeCamp community through a sponsorship program. We also offer $200 credits to freeCodeCamp developers to help them rapidly implement world-class customer identity and access management in their applications.","title":"One Vision, Many Paths: How We’re Supporting freeCodeCamp","tags":["LoginRadius","sponsorship","freeCodeCamp"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.3333333333333333,"src":"/static/abb83aaeb74765239bafebbba7e9cfd7/ee604/cover.png","srcSet":"/static/abb83aaeb74765239bafebbba7e9cfd7/69585/cover.png 200w,\n/static/abb83aaeb74765239bafebbba7e9cfd7/497c6/cover.png 400w,\n/static/abb83aaeb74765239bafebbba7e9cfd7/ee604/cover.png 800w,\n/static/abb83aaeb74765239bafebbba7e9cfd7/a8378/cover.png 1024w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Raghunath Reddy","github":"raghunath-r-a","avatar":null}}}},{"node":{"excerpt":"Introduction In C# 9.0, there are multiple features introduced. One of them is the Init-Only setters property feature. To use this feature…","fields":{"slug":"/engineering/csharp-init-only-setters-property/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<p>In C# 9.0, there are multiple features introduced. One of them is the <strong>Init-Only setters property</strong> feature. To use this feature, there are two pre-requisite.</p>\n<ol>\n<li>You should have the .NET 5 SDK installed in your system. If not, you can download and install it from <a href=\"https://dotnet.microsoft.com/download/dotnet/5.0\">here</a>.</li>\n<li>You should have at least a 16.7 version or the latest version of Visual Studio 2019. If not, then you have to update your Visual Studio 2019 to the latest version.</li>\n</ol>\n<p>After this setup, you are ready to go with the Init-Only setters property feature.</p>\n<p>Before knowing more about this feature, first, we will understand how we are using properties currently in C#.</p>\n<h2 id=\"how-we-are-using-the-properties-currently\" style=\"position:relative;\"><a href=\"#how-we-are-using-the-properties-currently\" aria-label=\"how we are using the properties currently permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How we are using the properties currently</h2>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk12\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Id</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">get</span><span class=\"mtk1\">; </span><span class=\"mtk12\">set</span><span class=\"mtk1\">; }</span></span></code></pre>\n<p>This is the way how we are using the properties, but whenever if we don't want to change the value of a property outside of a class and make them readable publicly, then we generally define the property as below.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk12\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Id</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">get</span><span class=\"mtk1\">; </span><span class=\"mtk10\">private</span><span class=\"mtk1\"> </span><span class=\"mtk12\">set</span><span class=\"mtk1\">; }</span></span></code></pre>\n<p>In that case, the Id property can not be set outside of the class, and to set this property, we have to introduce a constructor or a public method that can set the value of the Id field. Like below</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Company</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Id</span><span class=\"mtk1\"> { </span><span class=\"mtk4\">get</span><span class=\"mtk1\">; </span><span class=\"mtk4\">private</span><span class=\"mtk1\"> </span><span class=\"mtk4\">set</span><span class=\"mtk1\">; }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Company</span><span class=\"mtk1\">(</span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">) </span><span class=\"mtk3\">// Constructor</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">Id</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">id</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> </span><span class=\"mtk11\">SetId</span><span class=\"mtk1\">(</span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">) </span><span class=\"mtk3\">//Public method</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">Id</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">id</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Below are the problems which arise by using the above method</p>\n<ol>\n<li>We are not able to set the property value by using the <em>object initialization</em></li>\n<li>If we want to set the property as <em>immutable</em> (Value can not be changed), then we can not achieve this because any public method can change the value of that property, so here the property is <em>mutable</em> (Value can be changed).</li>\n</ol>\n<p>To fix those issues, In C# 9.0 Init-Only setters property feature was introduced. Have a look at this.</p>\n<h2 id=\"init-only-setters-property\" style=\"position:relative;\"><a href=\"#init-only-setters-property\" aria-label=\"init only setters property permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Init-Only Setters Property</h2>\n<p>Init-Only setters property gives us the flexibility to set the value of a property by using the object initializer as well the property is also immutable. So that will resolve the above issues, which were with the <em>private set</em> property.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Company</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Id</span><span class=\"mtk1\"> { </span><span class=\"mtk4\">get</span><span class=\"mtk1\">; init; }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">Company</span><span class=\"mtk1\"> </span><span class=\"mtk12\">comp</span><span class=\"mtk1\">=</span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Company</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Id</span><span class=\"mtk1\">=</span><span class=\"mtk7\">1</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}; </span><span class=\"mtk3\">// It works fine if we initialize here</span></span></code></pre>\n<p>As we can, it is perfectly fine to set the value during object initialization.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Company</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Id</span><span class=\"mtk1\"> { </span><span class=\"mtk4\">get</span><span class=\"mtk1\">; init; }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Company</span><span class=\"mtk1\">(</span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Id</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">Id</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>We can define the constructor as well to initialize the Init-Only setters property. </p>\n<p>If we will try to create a method in the class and want to change the value Init-Only setters property, then it will give us the compile-time error.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Company</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Id</span><span class=\"mtk1\"> { </span><span class=\"mtk4\">get</span><span class=\"mtk1\">; init; }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> </span><span class=\"mtk11\">SetId</span><span class=\"mtk1\">(</span><span class=\"mtk4\">int</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Id</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Id</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">Id</span><span class=\"mtk1\">; </span><span class=\"mtk3\">// Compile-time Error</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this article, we learned how we are setting the properties in C# currently and the new C# 9.0 feature Init-Only Setters Property. Also, we understood how this feature helps us to set the property value with the object initialization.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"July 15, 2021","updated_date":null,"description":"In this article, we will talk about Init-Only Setters Property in C#.","title":"C# Init-Only Setters Property","tags":["C#","Properties","Init"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/e2d2c98e4cd2dbf38d3e2ddeaba94705/ee604/coverimage.png","srcSet":"/static/e2d2c98e4cd2dbf38d3e2ddeaba94705/69585/coverimage.png 200w,\n/static/e2d2c98e4cd2dbf38d3e2ddeaba94705/497c6/coverimage.png 400w,\n/static/e2d2c98e4cd2dbf38d3e2ddeaba94705/ee604/coverimage.png 800w,\n/static/e2d2c98e4cd2dbf38d3e2ddeaba94705/f3583/coverimage.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Hemant Manwani","github":"hemant404","avatar":null}}}},{"node":{"excerpt":"What is a Content Security Policy (CSP), and why is it important? Overview A Content Protection Policy (CSP) is a security standard that…","fields":{"slug":"/engineering/content-security-policy/"},"html":"<p>What is a Content Security Policy (CSP), and why is it important?</p>\n<h2 id=\"overview\" style=\"position:relative;\"><a href=\"#overview\" aria-label=\"overview permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Overview</h2>\n<p>A Content Protection Policy (CSP) is a security standard that adds an extra layer of defense in detecting and mitigating certain kinds of attacks, such as Cross-Site Scripting (XSS), clickjacking, and other code injection threats. CSP is a preventative step against attacks that rely on executing malicious material in a trusted web context, as well as other attempts to bypass the same-origin policy.</p>\n<h2 id=\"what-threats-csp-can-mitigate\" style=\"position:relative;\"><a href=\"#what-threats-csp-can-mitigate\" aria-label=\"what threats csp can mitigate permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What Threats CSP Can Mitigate?</h2>\n<h3 id=\"1-mitigating-cross-site-scripting\" style=\"position:relative;\"><a href=\"#1-mitigating-cross-site-scripting\" aria-label=\"1 mitigating cross site scripting permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. Mitigating cross-site scripting</h3>\n<p>The CSP's main purpose is to prevent and report XSS attacks. XSS attacks take advantage of the browser's faith in the server's content. Because the browser trusts the source of the material without additional safety measures, the browser runs all code from a trustworthy origin. It is unable to distinguish which code is legal. Thus any injected malicious code is also executed.</p>\n<p>The website administrator can reduce the XSS attack using the CSP by defining trusted source sites for the executable scripts. When we use the CSP header, browsers only allow us to run the script from the whitelisted domains and ignore all other scripts.</p>\n<p>We can also use the same-origin policy (SOP) header to prevent the website from accessing data from the other origin. Still, Websites need to include lots of assets from external sources like content delivery networks (CDNs), Google Analytics scripts, fonts, styles, comment modules, social media buttons, etc., so for the modern web, we need to use CSP.  </p>\n<h3 id=\"2-mitigating-packet-sniffing-and-enforcing-https\" style=\"position:relative;\"><a href=\"#2-mitigating-packet-sniffing-and-enforcing-https\" aria-label=\"2 mitigating packet sniffing and enforcing https permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. Mitigating Packet Sniffing and Enforcing HTTPS</h3>\n<p>One interesting advantage of a content security policy is we can define the permitted protocols. For example, the sites can restrict browsers from loading content over HTTPS. Some browsers, by default, will not connect to HTTPS but using the content security policy, we can enforce browsers to encrypt conversations with your server. </p>\n<p>Sites may also leverage HTTP Strict-Transport-Security headers to ensure that browsers only connect to the site over encrypted routes.</p>\n<h2 id=\"understand-the-csp\" style=\"position:relative;\"><a href=\"#understand-the-csp\" aria-label=\"understand the csp permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Understand the CSP</h2>\n<h3 id=\"how-to-use-csp\" style=\"position:relative;\"><a href=\"#how-to-use-csp\" aria-label=\"how to use csp permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How to Use CSP?</h3>\n<p>Adding the Content-Security-Policy HTTP header to a web page and setting values for it allows you to restrict what resources the user agent is authorized to load for that page. For example, A page that allows loading external CSS or fonts but not allows loading javascript from the external domains.</p>\n<p>HTTP response headers are generally used to specify the Content-Security-Policy header, but if needed, you can also use HTML meta tags to provide specific CSP directives at the page level. </p>\n<p>An example of adding CSP headers is shown below. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk12\">Content</span><span class=\"mtk1\">-</span><span class=\"mtk12\">Security</span><span class=\"mtk1\">-Policy: </span><span class=\"mtk15\">default</span><span class=\"mtk1\">-</span><span class=\"mtk12\">src</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;self&#39;</span><span class=\"mtk1\">; </span><span class=\"mtk12\">img</span><span class=\"mtk1\">-</span><span class=\"mtk12\">src</span><span class=\"mtk1\"> *;  </span><span class=\"mtk12\">script</span><span class=\"mtk1\">-</span><span class=\"mtk12\">src</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\">.</span><span class=\"mtk12\">com</span><span class=\"mtk1\">;</span></span></code></pre>\n<p> An example of adding CSP headers in the HTML tags</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Content-Security-Policy&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;default-src &#39;self&#39;&quot;</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h2 id=\"csp-directive\" style=\"position:relative;\"><a href=\"#csp-directive\" aria-label=\"csp directive permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>CSP Directive</h2>\n<p>Listed below are a couple of CSP directives and their use cases:</p>\n<p><strong><code>Default-src</code></strong>: This directive serves as a fallback for the other CSP fetch directives. For absent directives like media-src and script-src, the user agent looks for the default-src directive's content and uses it.</p>\n<p><strong><code>Script-src</code></strong>: This directive is used to define locations from which external scripts can be loaded.</p>\n<p><strong><code>Img-src</code></strong>: Specifies sources from which images can be retrieved.</p>\n<p><strong><code>Media-src</code></strong>: This directive is used to define locations from which rich media like video can be retrieved.</p>\n<p><strong><code>Object-src</code></strong>: This directive is used to define locations from which plugins can be retrieved.</p>\n<p><strong><code>Font-src</code></strong>: Specifies permitted sources for loading fonts.</p>\n<p><strong><code>manifest-src</code></strong>: A list of acceptable source locations for web manifests. Web manifests are used by users of Progressive Web Applications to download websites and run them like native mobile apps.</p>\n<p><strong><code>frame-ancestors</code></strong>: A list of acceptable URL locations which this website can load in an iFrame.</p>\n<p><strong><code>form-action</code></strong>: A list of acceptable URL target locations where the website can send form data. It's most likely that you want this value set to <code>self</code>  as most websites only submit their form data locally. This property is not covered by default-src above, so make sure you set it.</p>\n<p><strong><code>plugin-types</code></strong>: The list of plugin types that can be loaded from the locations in object-src. Likely that you also want to set this to <code>none</code>.</p>\n<p><strong><code>base-uri</code></strong>: The list of URLs that can be used in HTML base tags on your site.</p>\n<p><strong><code>child-src</code></strong> is used to restrict permitted URLs for JavaScript workers and embedded frame contents, including embedded videos. In Level 3, frame-src and worker-src directives can be used instead to control embedded content and worker processes, respectively.</p>\n<p><strong><code>style-src</code></strong> is used to whitelist CSS stylesheet sources. To allow stylesheets from the current origin only, use style-src 'self'.</p>\n<p><strong><code>connect-src</code></strong> specifies permitted origins for direct JavaScript connections that use EventSource, WebSocket, or XMLHttpRequest objects.</p>\n<p>You can find a more updated and complete list maintained by Mozilla here.\nMozilla maintains a more up-to-date and comprehensive list, which can be seen <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP\">here</a>.</p>\n<h2 id=\"csp-browser-compatibility\" style=\"position:relative;\"><a href=\"#csp-browser-compatibility\" aria-label=\"csp browser compatibility permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>CSP Browser Compatibility</h2>\n<p> All major modern browsers have supported Content Security Policy.</p>\n<ol>\n<li>Chrome</li>\n<li>Firefox</li>\n<li>Safari</li>\n<li>Edge</li>\n<li>Opera</li>\n<li>Internet Explorer</li>\n<li>Chrome Android</li>\n<li>Firefox Android</li>\n<li>Safari on iOS</li>\n<li>Opera Android</li>\n<li>Samsung Internet</li>\n</ol>\n<p>Mozilla maintains a more up-to-date and comprehensive list for the CSP support in the browser, which can be seen <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP#browser_compatibility\">here</a>.</p>\n<h2 id=\"common-use-cases\" style=\"position:relative;\"><a href=\"#common-use-cases\" aria-label=\"common use cases permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Common Use cases</h2>\n<h3 id=\"user-case-1-sites-origin-only\" style=\"position:relative;\"><a href=\"#user-case-1-sites-origin-only\" aria-label=\"user case 1 sites origin only permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User case #1: Site's Origin only</h3>\n<p>The <code>default-src</code> directive in the below example policy is set to self. This permits the browser to load resources from the site's origin. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Content-Security-Policy&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;default-src &#39;self&#39;&quot;</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"user-case-2-trusted-domain-only\" style=\"position:relative;\"><a href=\"#user-case-2-trusted-domain-only\" aria-label=\"user case 2 trusted domain only permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User case #2: Trusted Domain only</h3>\n<p>The <code>default-src</code>  directive in the below example policy permits the browser to load resources from the trusted domain and all its subdomains.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Content-Security-Policy&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;default-src &#39;self&#39; *.loginradius.com&quot;</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>The above policy permits the browser to load content from loginradius.com as well as any subdomain under loginradius.com.</p>\n<h3 id=\"user-case-3-sslhttps-only\" style=\"position:relative;\"><a href=\"#user-case-3-sslhttps-only\" aria-label=\"user case 3 sslhttps only permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User case #3: SSL/HTTPS only</h3>\n<p>Suppose you are running an e-commerce site and want to ensure that all resources are only loaded via SSL or HTTPS. The below policy ensures that all of the resources on your website load from TLS.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Content-Security-Policy&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;default-src https:; script-src https: &#39;unsafe-inline&#39;; style-src https: &#39;unsafe-inline&#39;&quot;</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"user-case-4-trusted-executable-script-only\" style=\"position:relative;\"><a href=\"#user-case-4-trusted-executable-script-only\" aria-label=\"user case 4 trusted executable script only permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User case #4: Trusted Executable Script only</h3>\n<p>If you want to allow users of a web application to add images/photos from any source but permits all scripts from trusted sources or specific sources.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Content-Security-Policy&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;default-src &#39;self&#39; img-src *; script-src cdn.loginradius.com;&quot;</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p> The <code>img-src</code> directive allows images to load from anywhere.\nThe <code>script-src</code> directive can only accept executable scripts from cdn.loginradius.com.</p>\n<p> If you want to add social widgets like the google+ button, Facebook like, Tweet button on your website, you need to allow external script also like the below policy.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Content-Security-Policy&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;default-src &#39;self&#39; img-src *; script-src cdn.loginradius.com;https://platform.twitter.com; child-src https://plusone.google.com https://facebook.com https://platform.twitter.com;&quot;</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<h3 id=\"user-case-5-reporting-only\" style=\"position:relative;\"><a href=\"#user-case-5-reporting-only\" aria-label=\"user case 5 reporting only permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>User case #5: Reporting only</h3>\n<p>The <code>Content-Security-Policy-Report-Only</code> Header is a wonderful method to evaluate the effects of a Content-Security-Policy header without really blocking anything on the site. Also, we can get any violation reports using this header. By default, it only sends reports to the developer tools console. If you include a <code>report-to</code> or <code>report-uri</code> directive, it will send a JSON representation of the violation to the provided URI endpoint. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Content-Security-Policy-Report-Only&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;default-src &#39;self&#39;; report-uri https://report.yourwebsite.com/cspreport;&quot;</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>In the above example, it will not enforce anything. <code>Content-Security-Policy-Report-Only</code> policy only generates reports and sends them to the report URI. The CSP violation report is generated in JSON format. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">meta</span><span class=\"mtk1\"> </span><span class=\"mtk12\">http-equiv</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Content-Security-Policy-Report-Only&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">content</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;default-src &#39;self&#39;; script-src cdn.loginradius.com; report-uri https://report.loginradius.com/cspreport;&quot;</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>In the above example, the policy only allows the script from cdn.loginradius.com.</p>\n<h4 id=\"sample-html\" style=\"position:relative;\"><a href=\"#sample-html\" aria-label=\"sample html permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Sample Html</h4>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!</span><span class=\"mtk12\">DOCTYPE</span><span class=\"mtk1\"> </span><span class=\"mtk12\">html</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Content Security Policy</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">title</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&#39;text/javascript&#39;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">src</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&#39;https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js&#39;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">head</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    . . .</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">body</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">html</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>In the below sample HTML browser trying to download javascript from the other source, but we have allowed javascript src only from the CDN so that the browser will send the following violation report.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"json\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">&quot;csp-report&quot;</span><span class=\"mtk1\">:{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">&quot;document-uri&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;https://loginradius.com/test.html&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">&quot;referrer&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">&quot;blocked-uri&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">&quot;violated-directive&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;script-src cdn.loginradius.com&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">&quot;original-policy&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;default-src &#39;self&#39;; script-src cdn.loginradius.com; report-uri https://report.loginradius.com/cspreport;&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">&quot;disposition”: “report&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>The Content Security Policy will add an additional layer of protection to your web application. CSP is compatible with almost all current browsers and is widely used on the internet as an effective technique for decreasing the threat of cross-site scripting attacks.</p>\n<p>The Web Application Security Working Group of the Wide Web Consortium (w3c has already begun work on the specification's next <a href=\"https://www.w3.org/TR/CSP3/\">version, Content Security Policy Level 3</a> and Content Security Policy Level 2 already <a href=\"https://www.w3.org/TR/CSP2/\">Candidate Recommendation</a>.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n</style>","frontmatter":{"date":"July 14, 2021","updated_date":null,"description":null,"title":"Content Security Policy (CSP)","tags":["Secuirty Header","CSP","Content Security Policy"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/72be1a5572db6f2a09fd6baddad74fe9/14b42/content-security-policy.jpg","srcSet":"/static/72be1a5572db6f2a09fd6baddad74fe9/f836f/content-security-policy.jpg 200w,\n/static/72be1a5572db6f2a09fd6baddad74fe9/2244e/content-security-policy.jpg 400w,\n/static/72be1a5572db6f2a09fd6baddad74fe9/14b42/content-security-policy.jpg 800w,\n/static/72be1a5572db6f2a09fd6baddad74fe9/47498/content-security-policy.jpg 1200w,\n/static/72be1a5572db6f2a09fd6baddad74fe9/0e329/content-security-policy.jpg 1600w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Vijay Singh Shekhawat","github":"code-vj","avatar":null}}}},{"node":{"excerpt":"Authentication and user identity management are challenging tasks you are bound to run into when building applications. For example, you…","fields":{"slug":"/engineering/guest-post/user-authentication-in-python/"},"html":"<p>Authentication and user identity management are challenging tasks you are bound to run into when building applications. For example, you will need to create profiles for users, validate provided passwords, implement a password reset functionalities, manage user sessions (sometimes on multiple devices), manage social media authentication, and many others.</p>\n<p>You still have to work on other parts of your application, and you might not have a lot of time. A lot of developers might hack their way through authentication, but that could lead to improper implementations. It is not advisable to do this as you can create doorways for cyber-related attacks in your application.</p>\n<p>In this tutorial, you will learn how to properly implement user authentication and identity management in a Flask application.</p>\n<blockquote>\n<p>Here for the code alone? Head over to the <a href=\"#integrating-loginradius-with-python-and-flask\">implementation section</a> of this article or visit this <a href=\"https://gist.github.com/LordGhostX/01e9330dc4533a992a481fcd58fdd115\">GitHub gist</a> to browse demo code.</p>\n</blockquote>\n<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Introduction</h2>\n<h3 id=\"what-is-user-authentication\" style=\"position:relative;\"><a href=\"#what-is-user-authentication\" aria-label=\"what is user authentication permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What Is User Authentication?</h3>\n<p>User authentication is the process of validating a person’s identity to ascertain that they are who they claim to be. Authentication is achievable using passwords, one-time pins (OTP), biometrics, authentication apps, access tokens, certificates, and many more.</p>\n<h3 id=\"what-is-user-identity\" style=\"position:relative;\"><a href=\"#what-is-user-identity\" aria-label=\"what is user identity permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What Is User Identity?</h3>\n<p>User identity is an entity used to identify a user of an application uniquely. Forms of user identifiers include full names, email addresses, system-generated values, and <a href=\"https://en.wikipedia.org/wiki/Universally_unique_identifier\">UUIDs</a>.</p>\n<h3 id=\"what-is-an-identity-provider\" style=\"position:relative;\"><a href=\"#what-is-an-identity-provider\" aria-label=\"what is an identity provider permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What Is an Identity Provider?</h3>\n<p>An identity provider is a system that helps create, maintain, and manage user identity information. It also provides authentication services to external applications to ease their authentication flow and make it seamless.</p>\n<h2 id=\"what-is-authentication-in-python\" style=\"position:relative;\"><a href=\"#what-is-authentication-in-python\" aria-label=\"what is authentication in python permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What Is Authentication in Python?</h2>\n<p>When referring to authentication in <a href=\"https://www.python.org\">Python</a>, we talk about user authentication concerning web applications built with it. Python is actively used in making web applications with many supporting frameworks, including but not limited to <a href=\"https://flask.palletsprojects.com/en/2.0.x/\">Flask</a>, Django, FastAPI, Bottle, and Hug.</p>\n<p>Every web application built with Python at one point or another would need to implement user authentication features. This article will cover implementing authentication and proper handling of user identity information using <a href=\"https://loginradius.com\">LoginRadius</a> and Flask.</p>\n<h2 id=\"getting-started-with-loginradius\" style=\"position:relative;\"><a href=\"#getting-started-with-loginradius\" aria-label=\"getting started with loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Getting Started with LoginRadius</h2>\n<h3 id=\"what-is-loginradius\" style=\"position:relative;\"><a href=\"#what-is-loginradius\" aria-label=\"what is loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What Is LoginRadius?</h3>\n<p><a href=\"https://accounts.loginradius.com/auth.aspx?action=register&#x26;return_url=https://dashboard.loginradius.com/login\">LoginRadius</a> is a cloud-based consumer identity and access management (CIAM) platform that allows seamless user authentication and SSO integration into your application. LoginRadius is simple to use, completely secure, and highly customizable.</p>\n<p>To proceed with this tutorial, you will need an account with LoginRadius. If you have not created one before now, create one on the <a href=\"https://accounts.loginradius.com/auth.aspx?action=register&#x26;return_url=https://dashboard.loginradius.com/login\">LoginRadius website</a>.</p>\n<h3 id=\"benefits-of-using-loginradius\" style=\"position:relative;\"><a href=\"#benefits-of-using-loginradius\" aria-label=\"benefits of using loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Benefits of Using LoginRadius</h3>\n<ul>\n<li>It simplifies user management.</li>\n<li>It provides unmatched data, user, and account security.</li>\n<li>It ensures automatic privacy compliance.</li>\n<li>It integrates seamlessly into your applications.</li>\n<li>It provides scalable infrastructure.</li>\n</ul>\n<h1 id=\"integrating-loginradius-with-python-and-flask\">Integrating LoginRadius with Python and Flask</h1>\n<ul>\n<li>This section covers setting up the demo application that we will be integrating LoginRadius into in the remaining parts of the tutorial.</li>\n<li>It also covers LoginRadius integration with the Python and Flask demo application code.</li>\n</ul>\n<h3 id=\"acquiring-loginradius-api-credentials\" style=\"position:relative;\"><a href=\"#acquiring-loginradius-api-credentials\" aria-label=\"acquiring loginradius api credentials permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Acquiring LoginRadius API Credentials</h3>\n<p>Login to your <a href=\"https://accounts.loginradius.com/auth.aspx?return_url=https://dashboard.loginradius.com/login\">LoginRadius dashboard</a>, then navigate to the app you want to integrate with Python (LoginRadius will set up a free app for you when you create an account).</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 48.76923076923077%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAACC0lEQVQoz3VSy2oUQRQtdxpRMRGyMAFF1KhEicbFEGciJiiI4CLiwrUBF/6EC3/FRX7AlV8ggkFMFjIagk5Pz0y/u6u6uqv6eG81Mxux4FDU69Q5516xcP8ZljvPIa50sfXqLUxdIcsy6NogkZrWNer/gM+iQiNTGkmSIKV34uzqNhbXn0Jc6mDz5Rt4nodvB4fo/zyC54/gDX0MPMLwX0zP/OGY0N4V5289xOLaY4iLd9Hd2UVRFPjjDeGPxgjCEFGcIM8LZHlOaOfZOsudqkE8xiCh+1FECm9uYn71EcTSPXRf7ALWYjKZIElTIoshpXT2KkZVEdrZWAMeh/I33v34gPf9PXwN+xDnSOGFO9st4c5rNE3jsispQ20sElVDaSIwBjXBTMGEDTBQIT6N9vE5OcDHX8cQZ270MH97C2J53RHWVJQ4ndorkBJUSR9ojYLU5hQJzwzeM7qG1ZbIG3w5jiFOXt3A3PWuy7BHlrnKPhUjCIIWlKOmh6xck1KOwvd9FwvHoZSCaSwsyc1pLU5de4DTK91ZURo6TAoFWbGtxv1sKVcenF0uFVJZujtpId1n01GVigk3wLanGVoiiCm3UNZEameErLAsSyIskZLFSBmUpnH7baYWRwH14dxKDwtrT3DicsdVWSnpeswfTzAk6yFZZpspge1zOzG4R4Mwcpb5o0KV2Pvu4y/EuKSF93wBVwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"LoginRadius Dashboard\"\n        title=\"LoginRadius Dashboard\"\n        src=\"/static/f9afbe9d84c5cdd2af1ccf545eea1e27/e5715/pw6s1mqnn-yrtard7nbx.png\"\n        srcset=\"/static/f9afbe9d84c5cdd2af1ccf545eea1e27/a6d36/pw6s1mqnn-yrtard7nbx.png 650w,\n/static/f9afbe9d84c5cdd2af1ccf545eea1e27/e5715/pw6s1mqnn-yrtard7nbx.png 768w,\n/static/f9afbe9d84c5cdd2af1ccf545eea1e27/29007/pw6s1mqnn-yrtard7nbx.png 1600w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Next, head over to the <code>Configuration</code> tab on the LoginRadius sidebar (left side of the screen).</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 40.76923076923077%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsTAAALEwEAmpwYAAABO0lEQVQY012R3UrDMBzFA7KCY+jA4aWog1ZX8etGhY3VOZnXE7zx4XwM38J7X0DXrU2az3ZN1vlvw4p6OAn/0hx+6SlqXz0d9KdO78GfvIbhnDGmsiURabbMai9/KeIplynGWEiJWmejzvWk4fa90cvX94xShkmSMC6E/GdeWsAbMOcixgS1/WD/8tHp3rrDKTxTxsL5Ag7lWgMnz3NYlqm1Xlcqqp0xjnZ7Qedi3OjeucFzFGNtjNYGDlit/qrYCMI4YWjndLh3Pm4cl2EgK6UwJmmaVbJsIJdwY4wlmyr89jFDrZNB2793LBkTqCGK4oQyqZTMMrhILUss1oUNv39GqOn1t73B1uGNV5HhawmlZV1SwYIBuoEdZr0hWwnOynATwkdleBFhuCb8JWgrr1WP0Jg21sasSEJ/AIwagyczfrINAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"LoginRadius Configuration\"\n        title=\"LoginRadius Configuration\"\n        src=\"/static/2541852fcbc5a0ae25b8107c1e6fe890/e5715/i_alrgdnugpmtschkuuj.png\"\n        srcset=\"/static/2541852fcbc5a0ae25b8107c1e6fe890/a6d36/i_alrgdnugpmtschkuuj.png 650w,\n/static/2541852fcbc5a0ae25b8107c1e6fe890/e5715/i_alrgdnugpmtschkuuj.png 768w,\n/static/2541852fcbc5a0ae25b8107c1e6fe890/29007/i_alrgdnugpmtschkuuj.png 1600w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Your API credentials are located under the <code>API Key And Secret</code> section. Once you have retrieved this, copy the <code>APP Name</code>, <code>API Key</code>, and <code>API Secret</code> and store them somewhere secure and easily retrievable.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 53.38461538461539%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABAklEQVQoz41Sy07EMAzMv/M1fAMS4obEgQO3PYEAsW3zqJPm2ZDCJEVQrdRdRpYTWbVnxin7/EP5+jeWBjYSDZz3wyCVSvOcc8YYpNyQUqvNGccKVFBfR7DJOiEU5wL9mIJLy7xXNFrnvA8hhhBchQdQiyn9NGMM5pVSqu4GXBYckHVJPCMy3SAcCELyIfrKU3OO8V2Hg4rV4W6zsR2XatQjmd9QZPw0PX7o21eLj8pONzxb2FjVnqIs5ax0bNsceykkbYMLcqTvntX1gc4xg5a0Xl/oBBdXxuC2G6rnbUilrdZPR3N13928mD1yluZcXzKmbfiY8Ddwlx4692bmvYV/A5sxgDde+J2+AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"LoginRadius API credentials\"\n        title=\"LoginRadius API credentials\"\n        src=\"/static/c287d39ecf351e1775a3e5e8d1c4ba8b/e5715/7lev6yc_ebtxcg62wrbe.png\"\n        srcset=\"/static/c287d39ecf351e1775a3e5e8d1c4ba8b/a6d36/7lev6yc_ebtxcg62wrbe.png 650w,\n/static/c287d39ecf351e1775a3e5e8d1c4ba8b/e5715/7lev6yc_ebtxcg62wrbe.png 768w,\n/static/c287d39ecf351e1775a3e5e8d1c4ba8b/1acf3/7lev6yc_ebtxcg62wrbe.png 1596w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"whitelisting-your-domains\" style=\"position:relative;\"><a href=\"#whitelisting-your-domains\" aria-label=\"whitelisting your domains permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Whitelisting Your Domains</h3>\n<p>LoginRadius requires you to whitelist domains you will be integrating with your app. To whitelist, a domain, scroll down to the <code>Whitelist Your Domain</code> section in the <code>Configuration</code> tab of your app dashboard and add it.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 45.69230769230769%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA+klEQVQoz41RSVLEMAzMs3kAP+IFnLhy5UrILCRxkokXyZJtOhkCE+ZCV5eskktuqV0552drrXNr4gJRjMIRkGvyQ2K+pfOhCsTv9UdzOB5P57pphmFEvw/BexBn8CuZueyhqhXeMONkhmGhGXtj2q7v+h7xs+0QQRQRmONvZy4iUnEUSRlIK5Ysl7wd5TvNy8VemdGM5YhIRMsdSHOQdF+/vnOhCOUIq5LqKqwbU8np8eXw8Fz/VdzgWSqMDmPgNiyRPXpLnSXdA+tZH15Pc4gYW2S28zhNtHzSDkkkq9xWMKaqmPHy9NZajsvOEIlL9V/AgrD9NBNx/AKMSQv4EBNfaQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Domain Whitelisting\"\n        title=\"Domain Whitelisting\"\n        src=\"/static/3217ad727ff6eb3316cc85e9fee569e7/e5715/5ng50vbosmuhdhfuz-gi.png\"\n        srcset=\"/static/3217ad727ff6eb3316cc85e9fee569e7/a6d36/5ng50vbosmuhdhfuz-gi.png 650w,\n/static/3217ad727ff6eb3316cc85e9fee569e7/e5715/5ng50vbosmuhdhfuz-gi.png 768w,\n/static/3217ad727ff6eb3316cc85e9fee569e7/29007/5ng50vbosmuhdhfuz-gi.png 1600w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<blockquote>\n<p>By default, LoginRadius whitelists your local computer (localhost).</p>\n</blockquote>\n<h3 id=\"installing-loginradius-python-sdk\" style=\"position:relative;\"><a href=\"#installing-loginradius-python-sdk\" aria-label=\"installing loginradius python sdk permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Installing LoginRadius Python SDK</h3>\n<p>We need to install the LoginRadius Python SDK. It provides functionalities that allow Python programs to communicate with LoginRadius APIs.</p>\n<p>In the terminal, type:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">pip install LoginRadius-v2 requests cryptography pbkdf2</span></span></code></pre>\n<h3 id=\"setting-up-our-flask-server\" style=\"position:relative;\"><a href=\"#setting-up-our-flask-server\" aria-label=\"setting up our flask server permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setting up Our Flask Server</h3>\n<p>First, we need to install the Flask framework from PyPI. In the terminal, type:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"bash\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">pip install flask</span></span></code></pre>\n<p>After that, create a file named <code>server.py</code> and save the following code in it:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> flask </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> *</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">app = Flask(</span><span class=\"mtk12\">__name__</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">app.config[</span><span class=\"mtk8\">&quot;SECRET_KEY&quot;</span><span class=\"mtk1\">] = </span><span class=\"mtk8\">&quot;SECRET_KEY&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">index</span><span class=\"mtk1\">():</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Hello World!&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">__name__</span><span class=\"mtk1\"> == </span><span class=\"mtk8\">&quot;__main__&quot;</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    app.run(</span><span class=\"mtk12\">debug</span><span class=\"mtk1\">=</span><span class=\"mtk4\">True</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>When you run the <code>server.py</code> script and open your browser, you will get a response similar to the image below:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 44.61538461538462%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA40lEQVQoz2OI082Mtck2MojXlwj3MWoNNu8Nsepz125xVK53Uql3VKl31WgylAtVk3BQEbdHQwyxhoVeWjWWaoVG0qnmSpmWKjlWqjmmCpkm8lnmSrlAZKVWoK8QoSHjoyblrSrphYwYLLVjjdVjzdRjLbUTdJQCtBT9QEjB10gzwtYszcYk1cU2x9Eq29Y0w0w3yVAj1kgzDo4YDu49vmfn4Z3bDp46cfnmtYfXL9+/fgWGroLQtSsPrl29d+3KPQgXGTH8+/f3778/f//+/v//338SAQMy5x+JgOE/BWDgNAMA2huISzFg+LkAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Hello World\"\n        title=\"Hello World\"\n        src=\"/static/1947174e905bcfeb6e51672185574dd9/e5715/vordrrnvz-vekwuickak.png\"\n        srcset=\"/static/1947174e905bcfeb6e51672185574dd9/a6d36/vordrrnvz-vekwuickak.png 650w,\n/static/1947174e905bcfeb6e51672185574dd9/e5715/vordrrnvz-vekwuickak.png 768w,\n/static/1947174e905bcfeb6e51672185574dd9/525d3/vordrrnvz-vekwuickak.png 1090w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"initializing-the-loginradius-sdk\" style=\"position:relative;\"><a href=\"#initializing-the-loginradius-sdk\" aria-label=\"initializing the loginradius sdk permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Initializing the LoginRadius SDK</h3>\n<p>Update the <code>server.py</code> file with the code below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> LoginRadius </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> LoginRadius </span><span class=\"mtk15\">as</span><span class=\"mtk1\"> LR</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">LR.API_KEY = </span><span class=\"mtk8\">&quot;API Key&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">LR.API_SECRET = </span><span class=\"mtk8\">&quot;API Secret&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">loginradius = LR()</span></span></code></pre>\n<p>Replace the values of the <code>API_KEY</code> and <code>API_SECRET</code> variables with your LoginRadius application keys we saved earlier.</p>\n<h2 id=\"setting-up-user-registration\" style=\"position:relative;\"><a href=\"#setting-up-user-registration\" aria-label=\"setting up user registration permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setting up User Registration</h2>\n<p>To register users, you have to redirect them from your application to your LoginRadius Auth Page (IDX). Each LoginRadius app has a custom IDX. You can access it with the following URL pattern.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">https://{APP_NAME}.hub.loginradius.com/auth.aspx?action={AUTH_ACTION}&return_url={RETURN_URL}</span></code></pre>\n<ul>\n<li>The <code>APP_NAME</code> parameter refers to your LoginRadius app name, which you can retrieve from the <code>API Key And Secret</code> section in the <code>Configuration</code> tab of your dashboard.</li>\n<li>The <code>AUTH_ACTION</code> parameter refers to the authentication action you’re attempting to perform. It is either <code>register</code> or <code>login</code>.</li>\n<li>The <code>RETURN_URL</code> parameter refers to the URL LoginRadius should redirect your users to after successful authentication. It is usually a route on your application server.</li>\n</ul>\n<p>Update the <code>server.py</code> file with the code below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">LR_AUTH_PAGE = </span><span class=\"mtk8\">&quot;https://&lt;APP_NAME&gt;.hub.loginradius.com/auth.aspx?action=</span><span class=\"mtk4\">{}</span><span class=\"mtk8\">&return_url=</span><span class=\"mtk4\">{}</span><span class=\"mtk8\">&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/register/&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">register</span><span class=\"mtk1\">():</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\"># redirect the user to our LoginRadius register URL</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> redirect(LR_AUTH_PAGE.format(</span><span class=\"mtk8\">&quot;register&quot;</span><span class=\"mtk1\">, request.host_url))</span></span></code></pre>\n<p>In the code above, we created a <code>register</code> route that redirects users to our LoginRadius registration IDX. We also set our <code>AUTH_ACTION</code> to “register” and our <code>RETURN_URL</code> to our application home page.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 85.23076923076923%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqklEQVQ4y3WS/08SYRzH+ZfqF7Qm2dpaWtn8chyQyzZFnctVP7S5taUFLuAAVxuSWq2ttrasrRTTFZVDzMGR4N2BIOLANUVEhE7ggDueHu4UNemz1557P8/e793n+ewRiWvaq88pqyQdZ8931V7slVzo4bdKsaTjTK0SanFNR7VEWcWvp6vaTolvlBFJcR0E4UFdmBTHWnAtXBUuA4JroW7GNXAVDGUhIJJ5DegBCIXBrXzZ2OsbMYUm74Ze3l590Rd6rQwMN5IaqRe77huChjIilNQLSEl9u8/UuWy+5R/tXjb3+Ee6/c+6/OaewEin39zpG77pfSqnjDLSUI4chiH3Q2/sCV8esFt7O1v0TjyTjKeTsb1ELL0LALAlvNIljfyI/zDcSg01uAc/xhxgL2+xWGyzNrvNPvv9B8RqtSajO4t/1tAlnaxy2Dt02a0ej87Dn6yuhUi+CILweDzh9QgoADy50rSkrdy2gjJecavfb5bCBY7NZDKpVIqm6XQ6XWAL8BBPBhFC99/wJbfq3eZPwIF0NsMeKSafAyxw7QalBCanToTlJNZIPel339mMTbIsoOkUwzBZJgsRBAw7kyvNRKW2ZZQe9Rjb5vrmvV9gh1kmw7EcKAJIkSvmC3m+7ZXmhUEZcXJg8G04sMaZB3M+O+Brndl+vmEd2/j6m4kLJzDc8k2lwPXoQefHwg3T/Z9WnYI1mtud2MYn4ngsl9wPJ4KIVd2+UHpkx8OUXkEY6u2qDz6nMO2SHbbNlb5skdsP45pWj7HytOs8j8aj9rI7B69Op6Hg+C2cNhwY+u8joUrXkFHGJlJ3L/BqLDJjCluGw1PmyGcIFKbw1Ghk+mHwLULyFy5xEEYWtS2uxxDEpbmGq+sc/fWOAQgUR/TAVadKsJX4pUEJ7C8IDKqugjxwhgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"LoginRadius Login Page\"\n        title=\"LoginRadius Login Page\"\n        src=\"/static/813dfc4b51a3c6e998e0467ee788f277/e5715/smn-8jr5ahgmhtynezje.png\"\n        srcset=\"/static/813dfc4b51a3c6e998e0467ee788f277/a6d36/smn-8jr5ahgmhtynezje.png 650w,\n/static/813dfc4b51a3c6e998e0467ee788f277/e5715/smn-8jr5ahgmhtynezje.png 768w,\n/static/813dfc4b51a3c6e998e0467ee788f277/29007/smn-8jr5ahgmhtynezje.png 1600w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<blockquote>\n<p>NOTE: Don’t forget to replace the &#x3C;APP_NAME> placeholder with your LoginRadius app name we saved earlier.</p>\n</blockquote>\n<h3 id=\"authenticating-registered-users-user-login\" style=\"position:relative;\"><a href=\"#authenticating-registered-users-user-login\" aria-label=\"authenticating registered users user login permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Authenticating Registered Users (User Login)</h3>\n<p>To authenticate registered users, you have to redirect them to your IDX page, passing “login” as the <code>AUTH_ACTION</code>.</p>\n<p>Update the <code>server.py</code> file with the code below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login/&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">login</span><span class=\"mtk1\">():</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    access_token = request.args.get(</span><span class=\"mtk8\">&quot;token&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> access_token </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">None</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\"># redirect the user to our LoginRadius login URL if no access token is provided</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> redirect(LR_AUTH_PAGE.format(</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk1\">, request.base_url))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;You have successfully logged in!&quot;</span></span></code></pre>\n<blockquote>\n<p>When LoginRadius successfully authenticates a user, it attaches a <code>token</code> parameter to the <code>REDIRECT_URL</code> before redirecting your user there. This parameter contains the <a href=\"https://en.wikipedia.org/wiki/Access_token\">access token</a> of the user that we authenticated.</p>\n</blockquote>\n<p>In the code above, we redirect users to our LoginRadius login IDX if the <code>token</code> parameter is absent (this means LoginRadius did not redirect the user here). We also set our <code>AUTH_ACTION</code> to “login” and our <code>RETURN_URL</code> to our login page.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 85.23076923076923%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAAsTAAALEwEAmpwYAAACsklEQVQ4y3VS609ScRjmT8qtRVqhra118ZLK4YBazim2am31pbk+5BScwuGi2Zfaaqu+pctKTOcyTSSVcww8F1wc1kq0cxDkIgii50DvgUGa9O758Pze8zznfX7vfjL5ufbySu1pRceZ8zerLt5VXLidO2rlio6KSq38bHu5QgsAQUVV58mKthOnrpfJW8vkNwAyFW4EIDmgBKYiMCBqwtRMWPJ9JW4AguKYCodPBqQgBsjUjBktAGEwQCNj7KSfWNmxO95nt74/vc++aPUMVZN9DbSh2WMFfREylDIV0eYZfsC+HF63DfptjzcmBjdsQ5sTw78nLf5x7OdYF/tKTZkBRf0R80PfayLKZrNZPsBzHB/eDge2AjzPczwPTTzqU7kHNIf0f80ttLXW1fd+a1mMp22TH+25ms3VF/t8JBAiYj6UNKpLmxnrVZd+hFuAIf7NDYaWimEYiqLgCE1nxNuwaigdu4m2VLv0o5wDdEJGzGQygiCIokTEbEaKHWERafJ/zJdcujfc16yQje8m9g5VMpWEJhFhVSSmoY+ZNRRWTw91u+5xW+MCmBOx1F4qvS9VOp0GDmZn1NtIloqtpk2o29Jq73Iw05DwQDjI7AvJWCK2swN+EYJL2/Y2LvapyeMLY8yaZax+6tG8xw46bi88FXSthNlUMglj4V95s3JG14Sb0ELyI+baye4xdhl0nvi66de7D0FnLBoLhUKJ3YRkDrPIJ337ovTIjpppU9Oq+cqCbpRxSrFFQdq5IBwIQn75ObMXwQda3JbS277s7h3hHUV1Kr6b3kkCyd95JeqDhaH/PhJauoaGsdSR/cYfbxe312aC7tng6lyImtumgHwOuh0h5rl/WklhariwhIIZ+WZQEv0AhOi/5tRXL/XULPXm0FNziNc5dXmZhJUBlMT+ANjYr91wzuSxAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"LoginRadius Login Page\"\n        title=\"LoginRadius Login Page\"\n        src=\"/static/4a194cdf7efcbd7ff63dbe07e645ce76/e5715/7gs3xz6qhxhas7qgtjma.png\"\n        srcset=\"/static/4a194cdf7efcbd7ff63dbe07e645ce76/a6d36/7gs3xz6qhxhas7qgtjma.png 650w,\n/static/4a194cdf7efcbd7ff63dbe07e645ce76/e5715/7gs3xz6qhxhas7qgtjma.png 768w,\n/static/4a194cdf7efcbd7ff63dbe07e645ce76/29007/7gs3xz6qhxhas7qgtjma.png 1600w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 25.384615384615383%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAAsTAAALEwEAmpwYAAAApUlEQVQY02OIMSyw0cowkUv10G300m/yBCK9JieNGi1JP0URO0URByVRB0VREAlHcC6Dq16KtVaGhUaSkXqkqWa0uU68o3m2k0WunUm6tWGylWGypUGStVGylUESkAHkWhkkA7kW+onGmjEMly7euHj+2oXz186cvnT29OUb1+89vP/84YPnjx6+AKOXUPLBC6gImPHwwYsH958x/KcAYNH8j2gAAM8YyFMqo2EkAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"LoggedIn\"\n        title=\"LoggedIn\"\n        src=\"/static/778f9ef9e4f7ce2740faf879b8c1615a/e5715/xwzztcogdtmnyfq4j5nc.png\"\n        srcset=\"/static/778f9ef9e4f7ce2740faf879b8c1615a/a6d36/xwzztcogdtmnyfq4j5nc.png 650w,\n/static/778f9ef9e4f7ce2740faf879b8c1615a/e5715/xwzztcogdtmnyfq4j5nc.png 768w,\n/static/778f9ef9e4f7ce2740faf879b8c1615a/29007/xwzztcogdtmnyfq4j5nc.png 1600w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h2 id=\"fetching-user-profiles-from-access-tokens\" style=\"position:relative;\"><a href=\"#fetching-user-profiles-from-access-tokens\" aria-label=\"fetching user profiles from access tokens permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Fetching User Profiles From Access Tokens</h2>\n<p>We also want to fetch user profiles from the <code>access token</code> given by LoginRadius. It comes in handy when we want to verify if a given access token is valid (or has expired) or just fetch information about the current user.</p>\n<p>Update the <code>login</code> route with the code below. We also added a <code>dashboard</code> route where we will redirect users after successful authentication.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login/&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">login</span><span class=\"mtk1\">():</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    access_token = request.args.get(</span><span class=\"mtk8\">&quot;token&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> access_token </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">None</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\"># redirect the user to our LoginRadius login URL if no access token is provided</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> redirect(LR_AUTH_PAGE.format(</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk1\">, request.base_url))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\"># fetch the user profile details with their access tokens</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    result = loginradius.authentication.get_profile_by_access_token(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        access_token)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> result.get(</span><span class=\"mtk8\">&quot;ErrorCode&quot;</span><span class=\"mtk1\">) </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> </span><span class=\"mtk4\">None</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\"># redirect the user to our login URL if there was an error</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> redirect(url_for(</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    session[</span><span class=\"mtk8\">&quot;user_acccess_token&quot;</span><span class=\"mtk1\">] = access_token</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> redirect(url_for(</span><span class=\"mtk8\">&quot;dashboard&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/dashboard/&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">dashboard</span><span class=\"mtk1\">():</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;You have successfully logged in!&quot;</span></span></code></pre>\n<p>In the code above, we used the <code>authentication.get_profile_by_access_token</code> method from the LoginRadius SDK to fetch our user’s details. If the request was successful and the result does not contain an <code>ErrorCode</code> parameter, we save the access token in the user’s session and redirect them to the <code>dashboard</code> route. But if an error occurs somewhere, e.g., the access token is invalid/expired, we redirect the user back to the <code>login</code> route.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 25.384615384615383%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAi0lEQVQY02OIMSyw0cowkUv10G300m/yNGh2UK2xVazUlvJXFLFTFHFQEsWJGFz1Uqy1Miw0kozUI001oi104+1MMh3Msu1M062NkoHIXDfeSCPaWDMGEzFcunjj4vlrF85fO3P60tnTl29cv/fowfOHD54/evgCjF4C2Q/uP8OKGP5TALBo/kc0AAAUs8dlLi9TOAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"LoggedIn\"\n        title=\"LoggedIn\"\n        src=\"/static/f7ff18d73aa44304b1af09710f4dd5f2/e5715/f2p7ddnwin3yihucx2em.png\"\n        srcset=\"/static/f7ff18d73aa44304b1af09710f4dd5f2/a6d36/f2p7ddnwin3yihucx2em.png 650w,\n/static/f7ff18d73aa44304b1af09710f4dd5f2/e5715/f2p7ddnwin3yihucx2em.png 768w,\n/static/f7ff18d73aa44304b1af09710f4dd5f2/29007/f2p7ddnwin3yihucx2em.png 1600w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Next, we want to add more functionality to the <code>dashboard</code> route. Instead of just displaying a dummy text, let it show the user information we fetched earlier. Update the <code>dashboard</code> route with the code below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/dashboard/&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">dashboard</span><span class=\"mtk1\">():</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    access_token = session.get(</span><span class=\"mtk8\">&quot;user_acccess_token&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> access_token </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">None</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> redirect(url_for(</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\"># fetch the user profile details with their access tokens</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    result = loginradius.authentication.get_profile_by_access_token(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        access_token)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> result.get(</span><span class=\"mtk8\">&quot;ErrorCode&quot;</span><span class=\"mtk1\">) </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> </span><span class=\"mtk4\">None</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\"># redirect the user to our login URL if there was an error</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> redirect(url_for(</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> jsonify(result)</span></span></code></pre>\n<p>Here, we fetched the access token stored in the user’s session earlier, used it to get their details, and rendered the result.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 137.53846153846155%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAcCAIAAADuuAg3AAAACXBIWXMAAAsTAAALEwEAmpwYAAACr0lEQVQ4y5WUW08TQRTH91NgDN4iJVxKIEhtVS4VNIQHCYYoGBNDYkBERUh89MHEZx74TD5qTIgBQsKdXqDdW3dnOjuzM2fqLEtKS5Ctk5PJtJPfnjPn/M/RZnsWptIfuzteJ5rfvEitTiZXpgdWp/pXJ1MrI7FvT2Lfh1qX266PxJrSLU1DMWXX0lXTpruXx+JfUy2LfTdnUy3vk3fnH8QWlA20f37YutjftpyMzcXvPO+8PdF5a6L9xnhb87OqaYmumd6OmcGet8OJuUR8Ktn16n58uq/z5fDD+bHhpfHRL08HP42ml0aHAnuc+vCod67/3rvQtB9rud+bhfU/W79+ru3uZNS+sb6dz+nZTCFzpOwkly2qs9pDU1dV0wzL1k0buY6u66ZpWral60WMsecRyijnfuXfSyu6fM8UmEr1Q0oZ/ssYQwjJqKUVXJ4rAeWy9pOUUgVXopamI75xLDK28PzQ+RmMEY6GDcT3TWETGToPYRW2enY0fOLwzRPORF3YjLJGw97RxXZRhHyYM48Rj3nRsMr2vgmuJ72anKkiEUKiYQuLbElYZdAxCPjPsBW8awhWX6pGE6Zg9eBcSdR5bhC2sdgzBGbndToNW9X5NGxZbxfhstjWA89welcVCSo38GaHBHC2BBzOYc58YiDAXCIOrq8OYDOJ+UW4VA7CPrQEB1kDc+8YKQAsJgwmbMbzRFjsEvjQBNVYRQS1dUakoWxz5VlVy/FqtE1Z0BgyKmF5ix6YQHwJNXcCBBc82jNlvkPggkgqoiIJSAYRsAQoM6l6g4uzuga7L/wDxA8xOL70xBUi4RkbVEsrhVVhyqllGbIsgnbx4aphsGOIrQLPOwEfjoRAJLgBkZg4GICIBpNEiTQUWqDtMNsRMPKPLHApXNpVajaos+u6pcvWX24d58OOTRQqAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"LoggedIn\"\n        title=\"LoggedIn\"\n        src=\"/static/18bb6535f77c2607bb7398b12627fdad/e5715/1zsvbg3rk013zlbpxx2u.png\"\n        srcset=\"/static/18bb6535f77c2607bb7398b12627fdad/a6d36/1zsvbg3rk013zlbpxx2u.png 650w,\n/static/18bb6535f77c2607bb7398b12627fdad/e5715/1zsvbg3rk013zlbpxx2u.png 768w,\n/static/18bb6535f77c2607bb7398b12627fdad/05fb0/1zsvbg3rk013zlbpxx2u.png 1138w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"invalidating-access-tokens-user-logout\" style=\"position:relative;\"><a href=\"#invalidating-access-tokens-user-logout\" aria-label=\"invalidating access tokens user logout permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Invalidating Access Tokens (User Logout)</h3>\n<p>Invalidating access tokens means rendering particular access tokens useless and unusable. It comes in handy when we log out users. The LoginRadius SDK provides an <code>auth_in_validate_access_token</code> method that takes in an access token to be invalidated.</p>\n<p>To add this to our server, create a <code>logout</code> route with the code below:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">@app.route</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/logout/&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">logout</span><span class=\"mtk1\">():</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    access_token = session.get(</span><span class=\"mtk8\">&quot;user_acccess_token&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> access_token </span><span class=\"mtk4\">is</span><span class=\"mtk1\"> </span><span class=\"mtk4\">None</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> redirect(url_for(</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\"># invalidate the access token with LoginRadius API</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    loginradius.authentication.auth_in_validate_access_token(access_token)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    session.clear()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;You have successfully logged out!&quot;</span></span></code></pre>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 36.92307692307692%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA30lEQVQY02MoMCtMcCk30Uu3ks8ItZoQZjUh2mFKuM1EN81mJ5V6N/VWK6UMDSknVQlHVQkHNUlHNUknOGJwUEoylszWk0jUlohWFwtRFwsFozBd2Tg9+URjlVQj1XgN2QB1IJIJUBL3URD1giOGCL/iSP+y6ICK2KDqYO+CEJ/CUN+iEJ+i+Ij6xOjmlLjW9MSO5JjW5GgQig2tjwqugyOG169fvXr18u3bNy9evHj58uXz58+fPHny/v37/0QAhm/fv//79+/vn78I8OcvEvcfGGEHDD9+/PhPLqBIMwCZ9B/QHMr8mgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Log Out\"\n        title=\"Log Out\"\n        src=\"/static/7ee08aa463b99115f34baf4e3a011bcf/e5715/xyvodwpjtxjrjgxoffx5.png\"\n        srcset=\"/static/7ee08aa463b99115f34baf4e3a011bcf/a6d36/xyvodwpjtxjrjgxoffx5.png 650w,\n/static/7ee08aa463b99115f34baf4e3a011bcf/e5715/xyvodwpjtxjrjgxoffx5.png 768w,\n/static/7ee08aa463b99115f34baf4e3a011bcf/05fb0/xyvodwpjtxjrjgxoffx5.png 1138w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>This article taught us about user authentication, user identity management, and implementing it correctly. In addition, we saw how easy it is to integrate LoginRadius services into a Python application to ease the implementation of authentication and user identity management.</p>\n<p>The source code of the demo application is available as a <a href=\"https://gist.github.com/LordGhostX/01e9330dc4533a992a481fcd58fdd115\">GitHub gist</a>. You can learn more about the LoginRadius Python SDK features from the <a href=\"https://www.loginradius.com/developers/\">official documentation</a>.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n</style>","frontmatter":{"date":"July 07, 2021","updated_date":null,"description":"Learn about user authentication, user identity management, and implementing it correctly into a Python application using LoginRadius.","title":"Implementing User Authentication in a Python Application","tags":["Python","Authentication","Flask"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/9c74b4b9c19fc76911f54b82e0cceb74/14b42/coverImage.jpg","srcSet":"/static/9c74b4b9c19fc76911f54b82e0cceb74/f836f/coverImage.jpg 200w,\n/static/9c74b4b9c19fc76911f54b82e0cceb74/2244e/coverImage.jpg 400w,\n/static/9c74b4b9c19fc76911f54b82e0cceb74/14b42/coverImage.jpg 800w,\n/static/9c74b4b9c19fc76911f54b82e0cceb74/47498/coverImage.jpg 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Solomon Esenyi","github":"LordGhostX","avatar":null}}}},{"node":{"excerpt":"Hi Everyone 👋 !!! Today we are announcing the beta release of LoginRadius CLI. I am very much excited about it. Why LoginRadius CLI…","fields":{"slug":"/engineering/introducing-loginradius-cli/"},"html":"<p>Hi Everyone 👋 !!! Today we are announcing the beta release of <a href=\"https://github.com/LoginRadius/lr-cli#readme\">LoginRadius CLI</a>. I am very much excited about it.</p>\n<h2 id=\"why-loginradius-cli\" style=\"position:relative;\"><a href=\"#why-loginradius-cli\" aria-label=\"why loginradius cli permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why LoginRadius CLI?</h2>\n<p>Developer Experience plays a crucial role for us. We always think about the ways we can minimize the juggling between a quickstart tutorial, dashboard, and terminal.\nThe LoginRadius CLI will simplify your flow by just using some simple commands to <strong>register, login, add site, add social, etc.</strong>, and enables you to get the job done in very little time without leaving the terminal. </p>\n<h2 id=\"how-can-you-use-loginradius-cli\" style=\"position:relative;\"><a href=\"#how-can-you-use-loginradius-cli\" aria-label=\"how can you use loginradius cli permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How can you use LoginRadius CLI</h2>\n<p>Check out a few examples of how LoginRadius CLI can help manage your <a href=\"https://dashboard.loginradius.com/\">Loginradius Dashboard</a>.</p>\n<h3 id=\"loginregister-to-your-loginradius-dashboard\" style=\"position:relative;\"><a href=\"#loginregister-to-your-loginradius-dashboard\" aria-label=\"loginregister to your loginradius dashboard permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Login/Register to your LoginRadius Dashboard</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 39.23076923076923%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABoklEQVQoz5WS23PSQBSHM+OU224AxSC0EEhCuBUSbinQCi3QC9GOo6Pj5cGxHR8d/f/fPnehdXzxwYdvfntyzp6c3+4a1vkdjVlMfnmLDGJkf4v4b2JE7wYx/YRRdyJW3hFWYJNMlxCZQ6Q4Qii0SvkX4h/onN5rtTGEOyeV97Fe9PFaU3LPfdLZOvKpS8qskRBVkrK6Ux2LvKtwdqpr9DqTU5g2ohxgFNsLOt0Z3XDBYLzC9SPcZkS7d0ZvsGR6umV8ckkwumAwWeP4E2xnSLnap1IL1RAn2O6IguUjy32MbD1SDacch0uandme7ny36Tr+yP33X3y9+8G3+59sX39m/vIV8e0Xlqs3u3h1+Y5DO6DuDslVQoxC84zu8Zz+8GLXSE/hqr8Oow3dYMGzYotswdvbzNXVtFesr99zvnnL5uYDoXKVEBXS6lhEqacsN09pNoY0lE2/FeF4I1zFRDX0/DHFUouMrGDmasiszUGyxJOD4h8SqfI+p2pEsaMuRT0V0x5jKutSqaiOMGsT9FHo9eO3R3Ss8+aD7vMPNZ01vwHc4ORnyw0XpgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"alt_text\"\n        title=\"Login Command\"\n        src=\"/static/20378843f2b588ccb2e890368d4ad825/e5715/login.png\"\n        srcset=\"/static/20378843f2b588ccb2e890368d4ad825/a6d36/login.png 650w,\n/static/20378843f2b588ccb2e890368d4ad825/e5715/login.png 768w,\n/static/20378843f2b588ccb2e890368d4ad825/7a3d6/login.png 990w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>This command will help you to log in to the CLI. Once you logged in to the CLI, you can configure all your LoginRadius Applications through CLI. </p>\n<h3 id=\"manage-your-app-credentials\" style=\"position:relative;\"><a href=\"#manage-your-app-credentials\" aria-label=\"manage your app credentials permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Manage your App Credentials</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 78.15384615384615%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAACtklEQVQ4y41U2W7TUBC1hFC9Nk6c2PESx7ETx9kdN0uTNjRdVCGxCwEVQoD6wqfwzBcfZm4btUJtxcPRta9nztwzZ64ld30F7/wrjLMraMsv0A9voC0//ycodkW5i0/Qrv9A2louLgof5sSH+rwGdc8m1KDJNnTFeRzyPSh16M9MaOe/IGn7TehWCrPaRdnJYNpdWPUejEobMn2T9yMoBLXUEs8M1WxBryTQyregWN1oQLsgQtcfoZUuMZqeIIynGIw36I+PETQnqAdD+LQ6/gAVO0XYmoqYci2FYoTQiVgrRdDMGLpGCrfXkIJmgaS/QX5wik7vEEm6QDY8Qn90jHx2huX6JdabVxgXW0yKUxTzC/ToGxdjMkHKhDoRnvyEVDIjmLUuam4PjjcQAZbD7306SUecjpMZFTpZldrBexz/IKFNAQFJCaIJSd2gGRfoDtaI07kIZmm7RIZKfVWMplh3e3r5HqHjDuC3ZmhnS7S7C9heH4PJBo0oJ/lzsZ/2V2h1ZvDCsSDjAlxI1hti3dOpqOZB20kuVTskJRMJLNsit1mSWW0TOnAbI9EGj1Y3GIl9juWiLL/ZnsEkHuXFD0g1GhOWOp5uqdlH4jRsAL9nJJ1d5Qlg0+aHl8K4kpUIx9nAgEhTirOsGMrmO6QqGRJn65txIfe4f+wmk03n5xjlJ2KM+BsbddfHRyR7jQkanbUYnVZ3hSCeIUrJlN4xvObNKQoi5l7+a9CDpvBgJ8NT+PGChjcjOW06QSTABnAC7xmcdEtwNy473CP0Qpr+Lg1qmCOfXyLJVnCp4QzbH1L1RFw1TtLKj4CuIV89cVMqugeHZtEmc+o0QiZVj8KhQOBlMKg3uvoUXLp2tD6vQGWXVfrtKLMPkIu3kKdvoNC6l7++Bb0fvIP6JN5DXXyESr8y9dtv/AUIlLwDXYfWsAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"alt_text\"\n        title=\"API Credentials Commands\"\n        src=\"/static/6cbea556fc7286af4d9883543de16466/e5715/api-cred.png\"\n        srcset=\"/static/6cbea556fc7286af4d9883543de16466/a6d36/api-cred.png 650w,\n/static/6cbea556fc7286af4d9883543de16466/e5715/api-cred.png 768w,\n/static/6cbea556fc7286af4d9883543de16466/9c177/api-cred.png 880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Get your API Credentials in a single command. You can also reset your secret and generate sott using the LoginRadius CLI.</p>\n<h3 id=\"domain-whitelisting\" style=\"position:relative;\"><a href=\"#domain-whitelisting\" aria-label=\"domain whitelisting permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Domain Whitelisting</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 605px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 70.74380165289257%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACgUlEQVQ4y5VT227aQBBFlZrEu8YYYnOxDYSLMWBMgACxgRIoKYQqUtQ+NBD1mrc+9Rva5/7z6eyGRK2SqurD0eyOd87OmeON8Xffwd0pmL8Cb56DN3Zo/gf8JVRvBr7+htizyUe8NYv4GtWxuXAQv6oicWhBPchB5RRZ7t8Q556nwIMLxJSzW2TjNqyci5xdBncq4MkSWKIERTuCkjiSa54sQyXwp5CqQlUd8M4lYnzyQW5Uow6uV6EnXeiGh8OMh6zTgpltyLWqEymR/x7vwXW6jNvU4Rqxg3BD3XnIV4fIOG0U3AhOJUSjNUY4XqN/+grNYCILtVT5EdkfhK0VSQ5vkE5nUGsN0RucS6JCqQvPHyHonqHdm6Fz8hKDcIk85Q/ihacJVUG4FIRbZDJZVJt9tLtzuI0QTvFYEreOpyiUe7LDWiNCjkbAtOLfCcnt2P5wi3zBgtceUCcLKbFO3U3nV7SfE1EItx7idHwhZ8m0x5KFWQ+EjDrUE1mkMi6co45EKl0jeR1pSNpqSqI85XmiCIUk30N0K9fiEuGyJIw20CiZMOvy99ANF1Y+QNKsSZcN4XLao6IidNODmWvIfNb25RlxoWn54HzXoRJe0ww9WKUB0nYg53ZCsr1mJF3uDRZStmG1YJf6GEZLkr+muJJngs4ZfKphzLozZe/0Gm61i+niDcLJa3J3LI0YTS9hk8xi5QQuFfbJ5Yo3pLhCvTWBR6YF3Rm6w3P4nRniGo1A/DYs2kLbN6DG84jHHdm6HLB4TmItpAiIDiiyXRTfZW63V/cM+a5j7NNPsNkt4QuUyXuw8Q3YaCuhjDYPYA/x7hsbb+/OvqCa2WewOXFsfuAXI/yJS93EZyAAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"alt_text\"\n        title=\"Domain Commands\"\n        src=\"/static/f5950fca820daea07c795ea15241b7e4/90cbd/domain.png\"\n        srcset=\"/static/f5950fca820daea07c795ea15241b7e4/90cbd/domain.png 605w\"\n        sizes=\"(max-width: 605px) 100vw, 605px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Manage your white-listed domain for your application with simple commands.</p>\n<h3 id=\"theme-management\" style=\"position:relative;\"><a href=\"#theme-management\" aria-label=\"theme management permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Theme Management</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 60.46153846153845%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAByUlEQVQoz5WTW2+bQBCFeaqEF4ONuRtfMdflEhtUOWlIUBIllfKUqO/9D/3/0umwpmqjNm778GmG1eyZMztC0p+/IeheMb3/gtHhBawZqP+D5vUU26+QrLjD3ndgbH2MZBdMdig6UJgHZeT+I1Qr22CzENI4f8LETGF6F1gEDbKypTyH7uZQplsw4kd8nwDKZAPmFpCM6gFRdMBl+4woPWITNlhs9mBUoAww7Wf+J0StugKzOaRJ3sLzI1T1PbxliQ/MhzxeksgaIyo6J/QGrRfMaOT0FpYdYr4qsNxUMOxEiGmzHaZmKETPIY+HvDfRC2r8AZaTkVhC5MgKcryqsA5qJPknWF4mmNmxiIaTwPa4aGy6KRw/p3MOk87HTg5pVj6C8yPKwx2i7AqclpJXN/TdYb2rhUB/Wbci2HM+NODU4FdBakQN1dNSntA0dyj2nRAq9rdCjFctwuQo3nVOjlU9EG/7+8jLtyPrxSPK8prGu0bMr8jlpehqOql4w4kRCgd9PL+U9WnLwmHdoSSHVe+SRi4ubkS+iz9itT0IB6zfOF16F5UcWikkVnyGQuMoVgLNTqEOcWzGmLr0+H4BxYjA/gb9JWxR4zuefEPA4ACcsQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"alt_text\"\n        title=\"Theme Management Commands\"\n        src=\"/static/d2c52b4d79f1632b8cdf80e29412774b/e5715/theme.png\"\n        srcset=\"/static/d2c52b4d79f1632b8cdf80e29412774b/a6d36/theme.png 650w,\n/static/d2c52b4d79f1632b8cdf80e29412774b/e5715/theme.png 768w,\n/static/d2c52b4d79f1632b8cdf80e29412774b/d56e1/theme.png 1130w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>You can update the LoginRadius IDX Page theme from the predefined themes available through LoginRadius CLI. </p>\n<blockquote>\n<p>You can check out the <a href=\"\">Theme Customization</a> section in the LoginRadius Dashboard for all the available customization options.</p>\n</blockquote>\n<h3 id=\"add-social-logins\" style=\"position:relative;\"><a href=\"#add-social-logins\" aria-label=\"add social logins permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Social Logins</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 59.53846153846154%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAABz0lEQVQoz41SW1LbQBDUp6WVJRtZT8t6I+stG+PCMmCcVCDJATgB9z9DZ3YDFLgg5KOrZ1banumZlaIfT8iPD1C2P8HKe7D6AWpDqD8G+xfa35CsdIBjuNCMANp4AcbmGI1syLILeeRAIVYUT+SK4kKl75/Dg6QXR4TxBmV3QNUfkNd7LJILeEEPP17DDTqYbiVix2/BJjHUaSLAJiegM8msv6HrbrDkQnQpJLGsuEJyvkWUXcLyKozpx6l5Dt3IwPQIKhf9BEKwaa+RVwPmYQ/XbxCQsIgXLfxoJQQVLfxSTAhOlwd48xo2CflRT7YaITJzShFz8M7kcShEFRIV/AF4QUnPb+GQLTdcI0gvRVeTWUZzKzGzCxj28pVNKjI1c/FN5MQcZ1YuRqOdpZCM8g51M6Ak22G2RUGzDNMLMcu82qFo9jTLDXVciEtckHfNc5uc8TMuzhvhTiSr+Y6WltKuadvpGlm5oUrvh8/e2qT41f4byOPgr2Wnu0e/OmA7/KJNX8OaV4hpwx49F/5E2MvAn5+KOjnhkzPJru6wave0mApBlEHTA6hUTdND4sX/Q/UFJHb1CDXdgxHUbEc8QEkI8U4wS57zL8Dvs+URfwAbbkIPvNEj9QAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"alt_text\"\n        title=\"Social Commands\"\n        src=\"/static/4213e34da4f8ce6990c9dd5c6d550b21/e5715/social.png\"\n        srcset=\"/static/4213e34da4f8ce6990c9dd5c6d550b21/a6d36/social.png 650w,\n/static/4213e34da4f8ce6990c9dd5c6d550b21/e5715/social.png 768w,\n/static/4213e34da4f8ce6990c9dd5c6d550b21/6c2de/social.png 1334w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>With the help of LoginRadius CLI, you can add social logins to your LoginRadius IDX Page.</p>\n<h3 id=\"learn-more-about-the-loginradius--cli\" style=\"position:relative;\"><a href=\"#learn-more-about-the-loginradius--cli\" aria-label=\"learn more about the loginradius  cli permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Learn More about the LoginRadius  CLI</h3>\n<p>Run <code>lr --help</code> to get the list of all available commands. Also you can checkout the <a href=\"https://www.loginradius.com/open-source/cli/manual\">manual for all the commands supported</a>.</p>\n<h2 id=\"try-loginradius-cli\" style=\"position:relative;\"><a href=\"#try-loginradius-cli\" aria-label=\"try loginradius cli permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Try LoginRadius CLI</h2>\n<p>The LoginRadius CLI is available for Windows, macOS, and Linux. <a href=\"https://github.com/LoginRadius/lr-cli/tree/main#readme\">Check out the installation on our README</a>.</p>\n<h2 id=\"help-us-to-improve\" style=\"position:relative;\"><a href=\"#help-us-to-improve\" aria-label=\"help us to improve permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Help us to improve</h2>\n<p>We hope you’ll love the LoginRadius CLI. And we’re even more excited about the future as we explore what it looks like to build a truly delightful experience with LoginRadius on the command line. </p>\n<p>We can’t wait to hear about your experience with LoginRadius CLI, and we’d love your feedback. Please create an issue in our <a href=\"https://github.com/LoginRadius/lr-cli/issues\">open source repository</a> or discuss what more commands you feel should be there on our <a href=\"https://community.loginradius.com/\">community page</a>.</p>\n<p><a href=\"https://www.loginradius.com/open-source/cli\">Checkout for more details</a></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"July 02, 2021","updated_date":null,"description":"LoginRadius CLI helps you to perform basic actions of your LoginRadius Dashboard through the command line. The actions include login, register, logout, email configuration, domain whitelisting, etc.","title":"Introducing LoginRadius CLI","tags":["Authentication","DevTools","CLI","LoginRadius CLI"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/65b9c38d8aa61635972b0d2271c28c36/bc59e/cli.png","srcSet":"/static/65b9c38d8aa61635972b0d2271c28c36/69585/cli.png 200w,\n/static/65b9c38d8aa61635972b0d2271c28c36/497c6/cli.png 400w,\n/static/65b9c38d8aa61635972b0d2271c28c36/bc59e/cli.png 512w","sizes":"(max-width: 512px) 100vw, 512px"}}},"author":{"id":"Mohammed Modi","github":"mohammed786","avatar":null}}}}]},"markdownRemark":{"excerpt":"Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie…","fields":{"slug":"/engineering/identity-impact-of-google-chrome-thirdparty-cookie-restrictions/"},"html":"<p>Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie restrictions for 1% of stable clients and 20% of Canary, Dev, and Beta clients.</p>\n<p><strong>What does it mean for user authentication?</strong></p>\n<p>On one hand, Google believes third-party cookies are widely used for cross-site tracking, greatly affecting user privacy. Hence, Google wants to phase out (or restrict) supporting third-party cookies in Chrome by early Q2 2025 (subject to regulatory processes).</p>\n<p>On the other hand, Google introduced Privacy Sandbox to support the use cases (other than cross-site tracking and advertising) previously implemented using third-party cookies.</p>\n<p>In this article, we’ll discuss:</p>\n<ul>\n<li>How is user authentication (identity) affected?</li>\n<li>What is Google offering as part of Privacy Sandbox to support various identity use cases when third-party cookies are phased out?</li>\n</ul>\n<h2 id=\"how-is-user-authentication-affected\" style=\"position:relative;\"><a href=\"#how-is-user-authentication-affected\" aria-label=\"how is user authentication affected permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How is User Authentication Affected?</h2>\n<p>Third-party cookie restrictions affect user authentication in three ways, as follows.</p>\n<h3 id=\"external-identity-providers\" style=\"position:relative;\"><a href=\"#external-identity-providers\" aria-label=\"external identity providers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>External Identity Providers</h3>\n<p>If your website or app uses an external Identity Provider (IdP) — like LoginRadius, the IdP sets a third-party cookie when the user authenticates on your app.</p>\n<h3 id=\"web-sso\" style=\"position:relative;\"><a href=\"#web-sso\" aria-label=\"web sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Web SSO</h3>\n<p>If you have multiple apps across domains within your organization and authentication is handled using an IdP (internal or external) with web SSO, you already use third-party cookies to facilitate seamless access for each user using a single set of credentials.</p>\n<p>If you have implemented web SSO with one primary domain and multiple sub-domains of the primary domain, third-party cookie restrictions may not apply. For now, Google doesn’t consider the cookies set by sub-domains as third-party cookies, although this stance may change in the future.</p>\n<p>For example, you have apps at <code>example.com</code>, <code>travel.example.com</code>, <code>stay.example.com</code>, and web SSO is handled by <code>auth.example.com</code>. In this case, third-party cookie restrictions don’t apply.</p>\n<h3 id=\"federated-sso\" style=\"position:relative;\"><a href=\"#federated-sso\" aria-label=\"federated sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Federated SSO</h3>\n<p>Federated SSO is similar to, albeit different from, web SSO. It can handle multiple IdPs and applications—aka., Service Providers (SPs)—spanning multiple organizations. It can also implement authentication scenarios that are usually implemented through web SSO.</p>\n<p>Usually, authentication is handled on a separate pop-up or page when the user wants to authenticate rather than on the application or website a user visits. </p>\n<p>For example, you already use federated SSO if you facilitate authentication for a set of apps through multiple social identity providers as well as traditional usernames and passwords.</p>\n<blockquote>\n<p><strong>Note</strong>: It is also possible to store tokens locally, not within cookies. In this case, third-party cookie restrictions won’t affect token-based authentication. However, the restrictions still affect authentication where tokens are stored within third-party cookies (a common and secure method).</p>\n</blockquote>\n<h2 id=\"chromes-alternatives-for-third-party-cookies\" style=\"position:relative;\"><a href=\"#chromes-alternatives-for-third-party-cookies\" aria-label=\"chromes alternatives for third party cookies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Chrome’s Alternatives for Third-Party Cookies</h2>\n<p>Google has been developing alternative features and capabilities for Chrome to replace third-party cookies as part of its Privacy Sandbox for Web initiative.</p>\n<p>Specific to authentication, Google recommends the following:</p>\n<ol>\n<li>Cookies Having Independent Partitioned State (CHIPS)</li>\n<li>Storage Access API</li>\n<li>Related Website Sets</li>\n<li>Federated Credential Management (FedCM) API</li>\n</ol>\n<h3 id=\"cookies-having-independent-partitioned-state-chips\" style=\"position:relative;\"><a href=\"#cookies-having-independent-partitioned-state-chips\" aria-label=\"cookies having independent partitioned state chips permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cookies Having Independent Partitioned State (CHIPS)</h3>\n<p><a href=\"https://developers.google.com/privacy-sandbox/3pcd/chips\">CHIPS</a> are a restricted way of setting third-party cookies on a top-level site without making them accessible on other top-level sites. Thus, they limit cross-site tracking and enable specific cross-site functionalities, such as maps, chat, and payment embeds.</p>\n<p>For example, a user visits <code>a.com</code> with a map embed from <code>map-example.com</code>, which can set a partitioned cookie that is only accessible on a.com. </p>\n<p>If the user visits <code>b.com</code> with a map embed from <code>map-example.com</code>, it cannot access the partitioned cookie set on <code>a.com</code>. It has to create a separate partitioned cookie specific to <code>b.com</code>, thus blocking cross-site tracking yet allowing limited cross-site functionality.</p>\n<p>You should specifically opt for partitioned cookies (CHIPS), which are set with partitioned and secure cookie attributes.</p>\n<p>If you’re using an external identity provider for your application, CHIPS is a good option to supplant third-party cookie restrictions. </p>\n<p>However, CHIPS may not be ideal if you have a web SSO or federated SSO implementation. It creates separate partitioned cookies for each application with a separate domain, which can increase complexity and create compatibility issues.</p>\n<h3 id=\"storage-access-api\" style=\"position:relative;\"><a href=\"#storage-access-api\" aria-label=\"storage access api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Storage Access API</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/storage-access-api\">Storage Access API</a>, you can access the local storage in a third-party context through iframes, similar to when users visit it as a top-level site in a first-party context. That is, it gives access to unpartitioned cookies and storage.</p>\n<p>Storage Access API requires explicit user approval to grant access, similar to locations, camera, and microphone permissions. If the user denies access, unpartitioned cookies and storage won’t be accessible in a third-party context.</p>\n<p>It is most suitable when loading cross-site resources and interactions, such as:</p>\n<p>Verifying user sessions when allowing interactions on an embedded social post or providing personalization for an embedded video.\nEmbedded documents requiring user verification status to be accessible.</p>\n<p>As it requires explicit user approval, it is advisable to use Storage Access API when you can’t implement an identity use case with the other options.</p>\n<h3 id=\"related-website-sets\" style=\"position:relative;\"><a href=\"#related-website-sets\" aria-label=\"related website sets permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Related Website Sets</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/related-website-sets\">Related Website Sets</a>, you can declare a <code>primary</code> website and <code>associatedSites</code> for limited purposes to grant third-party cookie access and local storage for a limited number of sites.</p>\n<p>Chrome automatically recognizes related website sets declared, accepted, and maintained in this open-source GitHub repository: <a href=\"https://github.com/GoogleChrome/related-website-sets\">Related Website Sets</a></p>\n<p>It provides access through Storage Access API directly without prompting for user approval, but only after the user interacts with the relevant iframe.</p>\n<p>It is important to declare a limited number of domains in related website sets that are meaningful and used for specific purposes. Google may block or suspend any exploitative use of this feature.</p>\n<p>The top-level site can also request approval for specific cross-site resources and scripts to Storage Access API using <code>resuestStorageAccessFor()</code> API.</p>\n<p>If you’re using an external identity provider for your web application, you can declare the domain of the identity provider in the related set to ensure limited third-party cookies and storage access to the identity provider, thus ensuring seamless user authentication.</p>\n<p>Related Website Sets can also work to supplement third-party cookie restrictions in web SSO and federated SSO if the number of web applications (or domains) is limited.</p>\n<h3 id=\"federated-credential-management-fedcm-api\" style=\"position:relative;\"><a href=\"#federated-credential-management-fedcm-api\" aria-label=\"federated credential management fedcm api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Federated Credential Management (FedCM) API</h3>\n<p>FedCM API enables federated SSO without third-party cookies.</p>\n<p>With FedCM API, a user follows these steps for authentication:</p>\n<ol>\n<li>The User navigates to a Service Provider (SP) — aka., Relying Party (RP)</li>\n<li>As the user requests to authenticate, the SP requests the browser through FedCM API to initiate authentication.</li>\n<li>The browser displays a list of available identity providers (supported by the RP), such as social IdPs like Google, Apple, LinkedIn, and Facebook, or other OAuth IdPs like LoginRadius.</li>\n<li>Once the user selects an IdP, the browser communicates with the IdP. Upon valid authentication, the IdP generates a secure token.\nThe browser delivers this secure token to the RP to facilitate user authorization.</li>\n</ol>\n<p>You can access a user demo of FedCM here: <a href=\"https://fedcm-rp-demo.glitch.me/\">FedCM</a>. </p>\n<p>For more information about implementing federated SSO with FedCM API, go through the <a href=\"https://developers.google.com/privacy-sandbox/3pcd/fedcm-developer-guide\">FedCM developer guide</a>.</p>\n<h2 id=\"how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" style=\"position:relative;\"><a href=\"#how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" aria-label=\"how is loginradius preparing for the third party cookie phase out permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How is LoginRadius Preparing for the Third-party Cookie Phase-out?</h2>\n<p>Firstly, we’re committed to solving our customers' user identity pain points — and preparing for the third-party cookies phase-out is no different.</p>\n<p>We’ll implement the most relevant and widely useful solutions to facilitate a smooth transition for our customers.</p>\n<p>Please subscribe to our blog for more information. We’ll update you on how we help with the third-party cookie phase-out.</p>\n<h2 id=\"in-conclusion\" style=\"position:relative;\"><a href=\"#in-conclusion\" aria-label=\"in conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>In Conclusion</h2>\n<p>The proposed changes to phase out third-party cookies and suggested alternatives are evolving as Google has been actively collaborating and discussing changes with the border community.</p>\n<p>Moreover, browsers like Firefox, Safari, and Edge may approach restricting third-party cookies differently than Google does.</p>\n<p>From LoginRadius, we’ll keep you updated on what we’re doing as a leading Customer Identity and Access Management (CIAM) vendor to prepare for the third-party cookie phase-out.</p>\n<h2 id=\"glossary\" style=\"position:relative;\"><a href=\"#glossary\" aria-label=\"glossary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Glossary</h2>\n<p><strong>Top-level site</strong>: It is the primary site a user has visited.</p>\n<p><strong>First-party cookie</strong>: A cookie set by the top-level site.</p>\n<p><strong>Third-party cookie</strong>: A cookie set by a domain other than the top-level site. For example, let’s assume that a user has visited <code>a.com</code>, which might use an embed from <code>loginradius.com</code> to facilitate authentication. If <code>loginradius.com</code> sets a cookie when the user visits <code>a.com</code>, it is called a third-party cookie as the user hasn’t directly visited <code>loginradius.com</code>.</p>\n<h2 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>References</h2>\n<ul>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/prepare/prepare-for-phaseout\">Changes to Chrome's treatment of third-party cookies</a></li>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/guides/identity\">Check the impact of the third-party cookie changes on your sign-in workflows</a></li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"July 08, 2024","updated_date":null,"description":"Google Chrome has planned to phase out third-party cookies, which will affect different website functionalities depending on third-party cookies. This blog focuses on how this phase-out affects identity and user authentication and discusses alternatives for overcoming challenges.","title":"How Chrome’s Third-Party Cookie Restrictions Affect User Authentication?","tags":["Identity","Cookies","Chrome"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png","srcSet":"/static/eb7396060c0adc430dbed2d04b63d431/69585/third-party-cookies-phaseout-chrome.png 200w,\n/static/eb7396060c0adc430dbed2d04b63d431/497c6/third-party-cookies-phaseout-chrome.png 400w,\n/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png 800w,\n/static/eb7396060c0adc430dbed2d04b63d431/f3583/third-party-cookies-phaseout-chrome.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Raghunath Reddy","github":"raghunath-r-a","avatar":null}}}},"pageContext":{"limit":6,"skip":48,"currentPage":9,"type":"//engineering//","numPages":52,"pinned":"17fa0d7b-34c8-51c4-b047-df5e2bbaeedb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}