{"id":738,"date":"2022-06-18T17:36:51","date_gmt":"2022-06-18T17:36:51","guid":{"rendered":"https:\/\/codenerix.com\/?p=738\/"},"modified":"2023-04-06T06:24:32","modified_gmt":"2023-04-06T06:24:32","slug":"authentication-system","status":"publish","type":"post","link":"https:\/\/codenerix.com\/en\/authentication-system\/","title":{"rendered":"Authentication system"},"content":{"rendered":"\n<p>In this article, you will learn everything about <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong>&#8216;s authentication system.<\/p>\n\n\n\n<p>Every request that is getting to <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong> is passing through several middlewares, and some of them may be authentication backends. Those authentication backends are used to grant users into the system since some parts of its maybe have limited access.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Authentication<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Before communicating with the server, you must ensure you have enough rights to resolve the request as expected. Usually, when you work with a front-end, you will use views without permission to process data, so your <strong>Anonymous<\/strong> users won&#8217;t have problems using the website.<\/p>\n\n\n\n<p>Therefore, if you have an external app that would like to communicate using the <strong>API<\/strong> against views that require some permission levels, then you must know that <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong> will require a user to be granted into the system. If you do not wish to log in as a user, you must define some Public Views that will do the authentication job on your way (or avoid doing any). Of course, they can inherit from <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong> for certain features.<\/p>\n\n\n\n<p>For all the rest of us that don&#8217;t want to mess up with authentication, several mechanisms are working behind <strong>Django<\/strong> and <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong> to provide <strong>user-level access<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>One of the next <strong>Authentication<\/strong> systems must perform to log a user in:<ul><li><strong>Django Authentication System<\/strong> will decide if the user is granted into the system. This<\/li><\/ul> is the normal &amp; basic authentication system from Django, it will require a user and a password on the front end, and it will log the user in. The system will set a cookie on the user&#8217;s browser to make it work on successive requests. With this cookie, you can execute as many API requests as you want to, and you will get access to what you are granted.\n<ul class=\"wp-block-list\">\n<li><strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong>&#8216;s <strong>ActiveDirectory<\/strong> middleware will decide if the user is granted into the system. It will use an Active Directory server to determine if the user is granted. Some extra comments about this authentication method are at the end of the page.<\/li>\n\n\n\n<li><strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong>&#8216;s <strong>TokenAuth<\/strong> middleware will decide if the user is granted into the system. It is the system we will explain below since it is responsible for authenticating remote <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong>&#8216;s <strong>API<\/strong> requests.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong>&#8216;s <strong>LimitedAuth<\/strong> middleware will decide if the user is granted into the system <strong>right now<\/strong><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>When installing those middlewares from <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong>, set any &#8220;<strong>codenerix.authbackend<\/strong>&#8221; middleware straight after <strong>Django<\/strong>&#8216;s &#8220;<strong>AuthenticationMiddleware<\/strong>&#8220;. Example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">MIDDLEWARE = [\n    \"django.middleware.cache.UpdateCacheMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"django.middleware.locale.LocaleMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"codenerix.authbackend.TokenAuthMiddleware\",    &lt;--------------- It will be explained below\n    \"codenerix.authbackend.LimitedAuthMiddleware\",  &lt;--------------- It will be explained below\n    \"codenerix.authbackend.ActiveDirectoryGroupMembershipSSLBackend\", &lt;--- It will be explained at the end\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n    \"codenerix.middleware.SecureRequiredMiddleware\",   &lt;---- This one will make sure the website is working with HTTPS (depending on your config)\n    \"codenerix.middleware.CurrentUserMiddleware\",      &lt;---- This will let to have the logged in user object everywhere\n    \"django.middleware.cache.FetchFromCacheMiddleware\",\n]<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">GenPerson<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Remember that <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong>&#8216;s <strong>TokenAuth<\/strong> and <strong>LimitedAuth<\/strong> <strong>backends<\/strong> will check if the user is disabled at a certain moment. This is an optional feature that is auto-checked on every authentication request. To make your life easier, you can import &#8220;GenPerson&#8221; from <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong> and inherit from it in your model, for example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from codenerix.models_people import GenPerson\n\nclass Person(GenPerson, CodenerixModel):\n    phone = models.CharField(_(\"Phone\"), max_length=16, blank=True, null=True)<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>GenPerson<\/strong> will define a <strong>user<\/strong>, a <strong>name<\/strong>, a <strong>surname<\/strong>, a <strong>disabled<\/strong>, and a <strong>creator<\/strong> field. From models_people, you can import <strong>GenRole<\/strong> as well, which makes it easier to manage different roles for different people. We will talk about it in a different post.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>If you would like to implement the <strong>disabled<\/strong> feature yourself, you must link the &#8220;<strong>User<\/strong>&#8221; model from <strong>Django<\/strong> against another model, which must contain a field named &#8220;disabled&#8221;, which will be a DateTimeField, that links between the &#8220;<strong>User<\/strong>&#8221; <strong>model<\/strong> and your <strong>new model<\/strong> must have a <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">related_name<\/mark><\/strong> &#8220;<strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">person<\/mark><\/strong>&#8221; or &#8220;<strong>people<\/strong>&#8221; that are the ones <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong> will lookup to check if it can go forward to check if the user <strong>disabled<\/strong>, example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class Person(models.Model):\n    user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True, related_name='person')\n    name = models.CharField(_(\"Name\"), max_length=45, blank=False, null=False)\n    surname = models.CharField(_(\"Surname\"), max_length=90, blank=False, null=False)\n    disabled = models.DateTimeField(_(\"Disabled from\"), null=True, blank=True)<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">LimitedAuth<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>This <strong>auth-backend<\/strong> <strong>middleware<\/strong> is used to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Check how long the user has been without activity; it will kick it out if it has been away too long.<\/li>\n\n\n\n<li>Check if the user can be logged in at certain hours.<\/li>\n<\/ul>\n\n\n\n<p>In your configuration, you can use the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>SESSION_EXPIRE_WHEN_INNACTIVE:<\/strong> number of seconds the user can be inactive on the website without being logged out.<\/li>\n\n\n\n<li><strong>SESSION_SHIFTS:<\/strong> list of hours of the day when all users must be logged out.<\/li>\n<\/ul>\n\n\n\n<p>This middleware you must install after <strong>Django<\/strong>&#8216;s &#8220;<strong>AuthenticationMiddleware<\/strong>&#8220;:<br>        <code>django.contrib.auth.middleware.AuthenticationMiddleware<\/code><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">TokenAuth<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>The basics of <strong>TokenAuth<\/strong> are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Please send a request to some URL that will make a <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong> view answer (GenList, GenCreate, GenDetail, GenUpdate, GenDelete, or derived classes).<\/li>\n\n\n\n<li>The system will require you to include a few parameters in your request:\n<ul class=\"wp-block-list\">\n<li><strong>authtoken:<\/strong> this is the authentication token. We will extend the information below at &#8220;<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\">How does authtoken work<\/mark>&#8220;.<\/li>\n\n\n\n<li><strong>authuser:<\/strong> is the user we are authenticating against.<\/li>\n\n\n\n<li><strong>json:<\/strong> is the request we are trying to send to the server<\/li>\n\n\n\n<li><strong>force_rest_api:<\/strong> if it is defined (no matter the value), it will force the REST API. If it does not appear, this feature will be disabled (you may use any other way to enable REST API on your call,<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"> check below at &#8220;<em><strong>RESTful API<\/strong><\/em>&#8220;<\/mark>).<\/li>\n\n\n\n<li><strong>authjson_details:<\/strong> [optional, default=0] If we set it to &#8220;1&#8221; (or &#8220;true&#8221;, or &#8220;t&#8221;), it will return details included with the answer<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>How does <\/strong>authtoken<strong> work<\/strong><\/h3>\n\n\n\n<p><\/p>\n\n\n\n<p>To build the <strong>authtoken,<\/strong> we have several ways, and we must focus on our configuration since we can use several <strong>authtoken<\/strong> models for authentication.<\/p>\n\n\n\n<p>First, we must check our configuration and make sure that &#8220;<strong>AUTHENTICATION_DEBUG<\/strong>&#8221; is enabled and <strong>AUTHENTICATION_TOKEN<\/strong> is a <strong>dictionary<\/strong> configured as you expect authentication to work. Example with <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">debugging and all authentication methods <strong>enabled<\/strong><\/mark>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">AUTHENTICATION_DEBUG = True\nAUTHENTICATION_TOKEN = {\n    \"key\": \"hello\",\n    \"master_unsigned\": True,\n    \"master_signed\": True,\n    \"user_unsigned\": True,\n    \"user_signed\": True,\n    \"otp_unsigned\": True,\n    \"otp_signed\": True,\n}<\/pre>\n\n\n\n<p>The <strong>AUTHENTICATION_TOKEN<\/strong> dictionary has several entries. We will focus on the <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">last 6<\/mark>, <\/strong>which are combinations of:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>master, user &amp; top<\/strong>:<\/mark> those are authentication models<\/li>\n\n\n\n<li><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\"><strong>unsigned &amp; signed<\/strong>:<\/mark> those are variants to the authentication model<\/li>\n<\/ul>\n\n\n\n<p>The first entry, &#8220;<strong>key<\/strong>&#8220;, is directly associated with the &#8220;<strong>master<\/strong>&#8221; authentication model.<\/p>\n\n\n\n<p><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">Unsigned<\/mark><\/strong> variants will try to match the user&#8217;s given <strong>authtoken<\/strong> directly with the <strong>chosen key<\/strong> by the <strong>authentication mode<\/strong>l. Each model will choose the key for matching differently.<\/p>\n\n\n\n<p><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">Signed<\/mark><\/strong> variants do exist to sign the &#8220;<strong>json<\/strong>&#8221; string together with the &#8220;<strong>authuser<\/strong>&#8220;, so they can not be changed by a <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">man-in-the-middle<\/mark><\/strong>. <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">Signed<\/mark><\/strong> requests will be <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\"><strong>denied<\/strong> if the <strong>signature fails<\/strong><\/mark>.<\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"><strong>NOTES:<\/strong><\/mark><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\">We must mention that <strong>any request will be granted<\/strong> if <strong>just one<\/strong> of the authentication models<strong> answers positively<\/strong>.<\/mark><\/li>\n\n\n\n<li><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"><strong>All requests <\/strong>require <strong>authuser<\/strong> to be filled, and the <strong>user<\/strong> <strong>MUST EXIST<\/strong>.<\/mark><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Master authentication:<\/strong><\/h3>\n\n\n\n<p><\/p>\n\n\n\n<p>The &#8220;<strong>key<\/strong>&#8221; for authentication will be configured in your configuration&#8217;s &#8220;<strong>key<\/strong>&#8221; entry of the <strong>AUTHENTICATION_TOKEN<\/strong> dictionary.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">master<\/mark>_<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">unsigned<\/mark><\/strong>: the system will try to match &#8220;<strong>authtoken<\/strong>&#8221; with &#8220;<strong>key<\/strong>&#8220;. This is the most straight authentication method since all requests and users will match with the same &#8220;<strong>key<\/strong>&#8221; (the one in your configuration).<\/li>\n\n\n\n<li><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">master<\/mark>_<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">signed<\/mark><\/strong>: the system will try to match &#8220;<strong>authtoken<\/strong>&#8221; with <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">sha1( <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">authusername<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-black-color\"> + <\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">json<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-black-color\"> +<\/mark><\/strong> key )<\/mark><\/strong>\n<ul class=\"wp-block-list\">\n<li>In your <strong>config<\/strong>, &#8220;<strong>key<\/strong>&#8221; is configured with a string: &#8220;<strong>hello<\/strong>&#8220;<\/li>\n\n\n\n<li>In your request <strong>authuser<\/strong> is: &#8220;<strong>theuse<\/strong>r&#8221;<\/li>\n\n\n\n<li>In your request, <strong>json<\/strong> is: <strong>{}<\/strong><\/li>\n\n\n\n<li>The algorithm will be:<code><br>      <strong>sha1( <\/strong>\"theuser\" + \"{}\" + \"hello\" <strong>)<\/strong> = <br>      = <strong>sha1(<\/strong> \"theuser{}hello\" <strong>)<\/strong> =<br>      = 401339988b89ef71e34f614f78bba076550a1033<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>User authentication:<\/strong><\/h3>\n\n\n\n<p><\/p>\n\n\n\n<p>In every of our <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong> projects, we use a <strong>Person model <\/strong>to manage all the information about the people in the system. This model is linked <strong>1to1<\/strong> with the <strong>User model from Django<\/strong>. This means we don&#8217;t hold any real information from the user inside the <strong>User model from Django<\/strong>, neither &#8220;<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">First name<\/mark>&#8221; nor &#8220;<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">Last name<\/mark>&#8220;. All the rest of the fields are used as <strong>Django<\/strong> does &#8220;<strong>username<\/strong>&#8220;, &#8220;<strong>password<\/strong>&#8220;, &#8220;<strong>email<\/strong>&#8220;, &#8230; we make all of this simpler using <strong>GenPerson<\/strong> (explained at the beginning of this post).<\/p>\n\n\n\n<p>Since we decided not to work with &#8220;<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">First name<\/mark>&#8221; and &#8220;<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">Last name<\/mark>&#8221; to hold personal information, we use the &#8220;<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\"><strong>First name<\/strong><\/mark>&#8221; field from the <strong>User<\/strong> model from <strong>Django<\/strong> for the &#8220;<strong>User authentication<\/strong>&#8221; system. <strong><span style=\"color: #343433;\"><strong><a href=\"https:\/\/github.com\/codenerix\/django-codenerix\"><span style=\"color: #343433;\">CODE<\/span><span style=\"color: #70a8e0;\">NERIX<\/span><\/a><\/strong><\/span><\/strong> will use the string inside the &#8220;<strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">First name<\/mark><\/strong>&#8221; field as a <strong>key<\/strong>. To show this example, we will configure &#8220;<strong>abcdefgh<\/strong>&#8221; as the <strong>theuser<\/strong>&#8216;s <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">first&#8217;s name<\/mark>.<\/p>\n\n\n\n<p>In <strong>Django<\/strong>&#8216;s <strong>administration panel,<\/strong> it would look like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"623\" height=\"462\" src=\"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/codenerix_authtoken_user_system.png\" alt=\"\" class=\"wp-image-756\" srcset=\"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/codenerix_authtoken_user_system.png 623w, https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/codenerix_authtoken_user_system-480x356.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 623px, 100vw\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">user<\/mark>_<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">unsigned<\/mark><\/strong>: the system will try to match &#8220;<strong>authtoken<\/strong>&#8221; with the user&#8217;s <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\"><strong>First name<\/strong><\/mark> field from <strong>Django&#8217;s User model<\/strong>.<\/li>\n\n\n\n<li><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">user<\/mark>_<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">signed<\/mark><\/strong>: the system will try to match &#8220;<strong>authtoken<\/strong>&#8221; with <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">sha1( <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">authusername<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-black-color\"> + <\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">json<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-black-color\"> +<\/mark><\/strong> <\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">First Name<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\"> )<\/mark><\/strong>\n<ul class=\"wp-block-list\">\n<li>In your request, <strong>authuser<\/strong> is: &#8220;<strong>theuse<\/strong>r&#8221;   (and the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">First Name<\/mark> field from <strong>Django&#8217;s User model<\/strong> is &#8220;<strong>abcdefgh<\/strong>&#8221; )<\/li>\n\n\n\n<li>In your request, <strong>json<\/strong> is: <strong>{}<\/strong><\/li>\n\n\n\n<li>The algorithm will be:<br><code>      <strong>sha1( <\/strong>\"theuser\" + \"{}\" + \"abcdefgh\" <strong>)<\/strong> = <\/code><br><code>      = <strong>sha1( <\/strong>\"theuser{}abcdefgh\" <strong>)<\/strong> =<\/code><br><code>      = 0da2a3f2f7cf0ae0cebe254767c3ebb1667fd8d3<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>OTP authentication:<\/strong><\/h3>\n\n\n\n<p><\/p>\n\n\n\n<p>This authentication method works in the same way as the <strong>User authentication method<\/strong>. Still, instead of the user&#8217;s First name directly, it will use the <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">OTP number<\/mark><\/strong> created from using <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">First name<\/mark><\/strong> as the <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">seed for the OTP algorithm<\/mark><\/strong>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">user<\/mark>_<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">unsigned<\/mark><\/strong>: the system will try to match &#8220;<strong>authtoken<\/strong>&#8221; with the user&#8217;s <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">OTP( <\/mark><\/strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\"><strong>First name<\/strong><\/mark><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\"> )<\/mark><\/strong> field from <strong>Django&#8217;s User model<\/strong>.<\/li>\n\n\n\n<li><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">user<\/mark>_<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">signed<\/mark><\/strong>: the system will try to match &#8220;<strong>authtoken<\/strong>&#8221; with <strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">sha1( authusername<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-black-color\"> + <\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">json<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-black-color\"> + <\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">OTP( <\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">First Name<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\"> <\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-cyan-blue-color\">) <\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-luminous-vivid-amber-color\">)<\/mark><\/strong>\n<ul class=\"wp-block-list\">\n<li>In your request, <strong>authuser<\/strong> is: &#8220;<strong>theuse<\/strong>r&#8221;   (and the <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">First Name<\/mark> field from <strong>Django&#8217;s User model<\/strong> is &#8220;<strong>abcdefgh<\/strong>&#8221; )<\/li>\n\n\n\n<li>In your request, <strong>json<\/strong> is: <strong>{}<\/strong><\/li>\n\n\n\n<li>The algorithm will be:<br><code>      <strong>sha1( <\/strong>\"theuser\" + \"{}\" + <strong>OTP( <\/strong>\"abcdefgh\" <strong>)<\/strong> <strong>)<\/strong> = <\/code><br><code>      <strong>= sha1( <\/strong>\"theuser\" + \"{}\" + 633917 <strong>)<\/strong> <strong>)<\/strong> = <\/code><br><code>      = <strong>sha1( <\/strong>\"theuser{}633917\" <strong>)<\/strong> =<\/code><br><code>      = cfb51398eeefd28814a5e70f81a153be1c2a0c40<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Notes when using <strong>User<\/strong> and <strong>OTP<\/strong> authentication system:<\/h3>\n\n\n\n<p><\/p>\n\n\n\n<p>When using those authentication methods the first time, you may get an <strong>OSError exception<\/strong>, like this one:<\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"><strong>OSError:<\/strong> To use a<strong> user\/otp key,<\/strong> you have to set <strong>user_signed<\/strong>, <strong>user_unsigned<\/strong>, <strong>otp_signed,<\/strong> or <strong>otp_unsigned<\/strong> to <strong>True<\/strong> and set the <strong>user key<\/strong> in the user&#8217;s profile to some valid string as your token (<strong>first_name<\/strong> field in the <strong>user&#8217;s model<\/strong>)<\/mark><\/p>\n\n\n\n<p>The system requests you fill in the user&#8217;s &#8220;First name&#8221; with the authentication key to ensure those authentication methods will work properly.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ActiveDiretoryGroupMembershipoSSLBackend<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>This is the authorization backend for Active Directory in Django.<\/p>\n\n\n\n<p>This authentication method has been working in production for a long time on old servers. We are unsure how the compatibility is on servers nowadays since we have not tested it. The feature is here and can be improved or fixed if it lacks compatibility, so you are welcome to send Pull Requests.<\/p>\n\n\n\n<p>We won&#8217;t explain much about this feature since we consider it to be an advanced feature. Anyway, some description is required so advanced users can use it.<\/p>\n\n\n\n<p>To get it working, you must add it to middleware (check the example at the top of this post) and then set the configuration with the next fields:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Authorization backend for Active Directory in Django\n\n# Configuration parameters\n# AD_SSL = True                             # Use SSL\n# AD_CERT_FILE='\/path\/to\/your\/cert.txt'     # Path to SSL certificate\n# AD_DEBUG_FILE='\/tmp\/ldap.debug'           # Path to DEBUG file (if none, Debugging will be disabled)\n# AD_LDAP_PORT=9834                         # Port to use\n# AD_DNS_NAME='NTDOMAIN.CODENERIX.COM'      # DNS nameserver if different than NT4 DOMAIN\nAD_LOCK_UNAUTHORIZED=True                   # Unauthorized users in Active Directory should be locked in Django\nAD_NT4_DOMAIN='NTDOMAIN.CODENERIX.COM'      # NT4 Domain name\nAD_MAP_FIELDS= {                            # Fields to map:   left=Django   right=Active Directory\n    'email':        'mail',\n    'first_name':   'givenName',\n    'last_name':    'sn',\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In this article, you will learn everything about CODENERIX&#8216;s authentication system. Every request that is getting to CODENERIX is passing through several middlewares, and some of them may be authentication backends. Those authentication backends are used to grant users into the system since some parts of its maybe have limited access. Authentication Before communicating with [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":795,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[20],"tags":[],"class_list":["post-738","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-howto"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Authentication system - Codenerix<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/codenerix.com\/en\/authentication-system\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Authentication system - Codenerix\" \/>\n<meta property=\"og:description\" content=\"In this article, you will learn everything about CODENERIX&#8216;s authentication system. Every request that is getting to CODENERIX is passing through several middlewares, and some of them may be authentication backends. Those authentication backends are used to grant users into the system since some parts of its maybe have limited access. Authentication Before communicating with [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/codenerix.com\/en\/authentication-system\/\" \/>\n<meta property=\"og:site_name\" content=\"Codenerix\" \/>\n<meta property=\"article:published_time\" content=\"2022-06-18T17:36:51+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-04-06T06:24:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/authenticate.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"628\" \/>\n\t<meta property=\"og:image:height\" content=\"353\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Codenerix\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Codenerix\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/codenerix.com\/en\/authentication-system\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/codenerix.com\/en\/authentication-system\/\"},\"author\":{\"name\":\"Codenerix\",\"@id\":\"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af\"},\"headline\":\"Authentication system\",\"datePublished\":\"2022-06-18T17:36:51+00:00\",\"dateModified\":\"2023-04-06T06:24:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/codenerix.com\/en\/authentication-system\/\"},\"wordCount\":1666,\"image\":{\"@id\":\"https:\/\/codenerix.com\/en\/authentication-system\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/authenticate.webp\",\"articleSection\":[\"Howto\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/codenerix.com\/en\/authentication-system\/\",\"url\":\"https:\/\/codenerix.com\/en\/authentication-system\/\",\"name\":\"Authentication system - Codenerix\",\"isPartOf\":{\"@id\":\"https:\/\/codenerix.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/codenerix.com\/en\/authentication-system\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/codenerix.com\/en\/authentication-system\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/authenticate.webp\",\"datePublished\":\"2022-06-18T17:36:51+00:00\",\"dateModified\":\"2023-04-06T06:24:32+00:00\",\"author\":{\"@id\":\"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af\"},\"breadcrumb\":{\"@id\":\"https:\/\/codenerix.com\/en\/authentication-system\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/codenerix.com\/en\/authentication-system\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/codenerix.com\/en\/authentication-system\/#primaryimage\",\"url\":\"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/authenticate.webp\",\"contentUrl\":\"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/authenticate.webp\",\"width\":628,\"height\":353},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/codenerix.com\/en\/authentication-system\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/codenerix.com\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Authentication system\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/codenerix.com\/#website\",\"url\":\"https:\/\/codenerix.com\/\",\"name\":\"Codenerix\",\"description\":\"Framework libre Open Source\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/codenerix.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af\",\"name\":\"Codenerix\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/codenerix.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dee2772994eb5d89e57afac281bca674800da15c6c32fba528dea162570d644d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/dee2772994eb5d89e57afac281bca674800da15c6c32fba528dea162570d644d?s=96&d=mm&r=g\",\"caption\":\"Codenerix\"},\"url\":\"https:\/\/codenerix.com\/en\/author\/codenerix\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Authentication system - Codenerix","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/codenerix.com\/en\/authentication-system\/","og_locale":"en_US","og_type":"article","og_title":"Authentication system - Codenerix","og_description":"In this article, you will learn everything about CODENERIX&#8216;s authentication system. Every request that is getting to CODENERIX is passing through several middlewares, and some of them may be authentication backends. Those authentication backends are used to grant users into the system since some parts of its maybe have limited access. Authentication Before communicating with [&hellip;]","og_url":"https:\/\/codenerix.com\/en\/authentication-system\/","og_site_name":"Codenerix","article_published_time":"2022-06-18T17:36:51+00:00","article_modified_time":"2023-04-06T06:24:32+00:00","og_image":[{"width":628,"height":353,"url":"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/authenticate.webp","type":"image\/webp"}],"author":"Codenerix","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Codenerix","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/codenerix.com\/en\/authentication-system\/#article","isPartOf":{"@id":"https:\/\/codenerix.com\/en\/authentication-system\/"},"author":{"name":"Codenerix","@id":"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af"},"headline":"Authentication system","datePublished":"2022-06-18T17:36:51+00:00","dateModified":"2023-04-06T06:24:32+00:00","mainEntityOfPage":{"@id":"https:\/\/codenerix.com\/en\/authentication-system\/"},"wordCount":1666,"image":{"@id":"https:\/\/codenerix.com\/en\/authentication-system\/#primaryimage"},"thumbnailUrl":"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/authenticate.webp","articleSection":["Howto"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/codenerix.com\/en\/authentication-system\/","url":"https:\/\/codenerix.com\/en\/authentication-system\/","name":"Authentication system - Codenerix","isPartOf":{"@id":"https:\/\/codenerix.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/codenerix.com\/en\/authentication-system\/#primaryimage"},"image":{"@id":"https:\/\/codenerix.com\/en\/authentication-system\/#primaryimage"},"thumbnailUrl":"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/authenticate.webp","datePublished":"2022-06-18T17:36:51+00:00","dateModified":"2023-04-06T06:24:32+00:00","author":{"@id":"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af"},"breadcrumb":{"@id":"https:\/\/codenerix.com\/en\/authentication-system\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/codenerix.com\/en\/authentication-system\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/codenerix.com\/en\/authentication-system\/#primaryimage","url":"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/authenticate.webp","contentUrl":"https:\/\/codenerix.com\/wp-content\/uploads\/2022\/06\/authenticate.webp","width":628,"height":353},{"@type":"BreadcrumbList","@id":"https:\/\/codenerix.com\/en\/authentication-system\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/codenerix.com\/en\/"},{"@type":"ListItem","position":2,"name":"Authentication system"}]},{"@type":"WebSite","@id":"https:\/\/codenerix.com\/#website","url":"https:\/\/codenerix.com\/","name":"Codenerix","description":"Framework libre Open Source","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/codenerix.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/codenerix.com\/#\/schema\/person\/c1dce0f30541a2be119ee8adc332a9af","name":"Codenerix","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/codenerix.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/dee2772994eb5d89e57afac281bca674800da15c6c32fba528dea162570d644d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dee2772994eb5d89e57afac281bca674800da15c6c32fba528dea162570d644d?s=96&d=mm&r=g","caption":"Codenerix"},"url":"https:\/\/codenerix.com\/en\/author\/codenerix\/"}]}},"_links":{"self":[{"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/posts\/738","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/comments?post=738"}],"version-history":[{"count":26,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/posts\/738\/revisions"}],"predecessor-version":[{"id":856,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/posts\/738\/revisions\/856"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/media\/795"}],"wp:attachment":[{"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/media?parent=738"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/categories?post=738"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codenerix.com\/en\/wp-json\/wp\/v2\/tags?post=738"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}