Answers.Body: <p>The basic user identity relies on login and password, so you will have to create your own class to represent an identity based on something else, like a token for example:</p>
  
  <pre><code>&lt;?php
  
  namespace Craft;
  
  class TokenIdentity extends UserIdentity
  {
      private $_id;
      public $token;
  
      public function __construct($token)
      {
          $this-&gt;token = $token;
      }
  
      public function authenticate()
      {
          $socialUser = craft()-&gt;social-&gt;getUserByEncodedToken($this-&gt;token);
  
          if($socialUser) {
              $this-&gt;_id = $socialUser-&gt;user-&gt;id;
              $this-&gt;username = $socialUser-&gt;user-&gt;username;
              $this-&gt;errorCode = static::ERROR_NONE;
  
              return true;
          } else {
              return false;
          }
      }
  
      public function getId()
      {
          return $this-&gt;_id;
      }
  }
  </code></pre>
  
  <p>Then you'll need to create your own user session service to be able to authenticate the user (with a token for example):</p>
  
  <pre><code>&lt;?php
  
  namespace Craft;
  
  class Social_UserSessionService extends UserSessionService {
  
      private $_identity;
      public $allowAutoLogin = true;
  
      public function init()
      {
          $this-&gt;setStateKeyPrefix(md5('Yii.Craft\UserSessionService.'.craft()-&gt;getId()));
  
          parent::init();
      }
  
      public function login(Oauth_TokenModel $token)
      {
          $rememberMe = true;
  
          $this-&gt;_identity = new TokenIdentity($token-&gt;encodedToken);
          $this-&gt;_identity-&gt;authenticate();
  
          // Was the login successful?
          if ($this-&gt;_identity-&gt;errorCode == TokenIdentity::ERROR_NONE)
          {
              // Get how long this session is supposed to last.
  
              $this-&gt;authTimeout = craft()-&gt;config-&gt;getUserSessionDuration($rememberMe);
  
              $id = $this-&gt;_identity-&gt;getId();
  
              $user = craft()-&gt;users-&gt;getUserById($id);
  
              $states = $this-&gt;_identity-&gt;getPersistentStates();
  
  
              // Run any before login logic.
              if ($this-&gt;beforeLogin($id, $states, false))
              {
                  // Fire an 'onBeforeLogin' event
                  $this-&gt;onBeforeLogin(new Event($this, array(
                      'username'      =&gt; $user-&gt;username,
                  )));
  
                  $this-&gt;changeIdentity($id, $this-&gt;_identity-&gt;getName(), $states);
  
                  // Fire an 'onLogin' event
                  $this-&gt;onLogin(new Event($this, array(
                      'username'      =&gt; $user-&gt;username,
                  )));
  
                  if ($this-&gt;authTimeout)
                  {
                      if ($this-&gt;allowAutoLogin)
                      {
                          if ($user)
                          {
                              // Save the necessary info to the identity cookie.
                              $sessionToken = StringHelper::UUID();
                              $hashedToken = craft()-&gt;security-&gt;hashData(base64_encode(serialize($sessionToken)));
                              $uid = craft()-&gt;users-&gt;handleSuccessfulLogin($user, $hashedToken);
  
                              $data = array(
                                  $this-&gt;getName(),
                                  $sessionToken,
                                  $uid,
                                  ($rememberMe ? 1 : 0),
                                  craft()-&gt;request-&gt;getUserAgent(),
                                  $this-&gt;saveIdentityStates(),
                              );
  
                              $this-&gt;saveCookie('', $data, $this-&gt;authTimeout);
                          }
                          else
                          {
                              throw new Exception(Craft::t('Could not find a user with Id of {userId}.', array('{userId}' =&gt; $this-&gt;getId())));
                          }
                      }
                      else
                      {
                          throw new Exception(Craft::t('{class}.allowAutoLogin must be set true in order to use cookie-based authentication.', array('{class}' =&gt; get_class($this))));
                      }
                  }
  
                  $this-&gt;afterLogin(false);
              }
  
              return !$this-&gt;getIsGuest();
          }
  
          Craft::log('Tried to log in unsuccessfully.', LogLevel::Warning);
          return false;
      }
  }
  </code></pre>
  
  <p>This code comes from a plugin which is still under development so don't take for granted it's all secure or the best way to achieve this, but hopefully it will help you get started !</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-09-24T13:01:54.990Z
Answers.Text: I was planning to use tokens, so this looks like the perfect place to start. Thanks!
Answers.UserDisplayName: Shane Hudson
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-09-24T13:00:12.847Z
Answers.LastActivityDate: 2014-09-24T22:42:39.447Z
Answers.LastEditDate: 2014-09-24T22:42:39.447Z
Answers.UserDisplayName: Benjamin David
Answers.Body: <p>What about setting up a relation between your CustomUserAuthModel and the UserModel, check if everything is alright through your plugin with IndieAuth, and then login, through UserSessionService->impersonate()?</p>
  
  <pre><code>The new user session will only last as long as the browser session remains active; no identity cookie will be * created.
  </code></pre>
  
  <p>Not sure if that will work for you, but might be worth a try?</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-09-24T13:01:31.023Z
Answers.Text: I didn't know about impersonate, that could be quite useful thanks!
Answers.UserDisplayName: Shane Hudson
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-09-24T11:04:56.943Z
Answers.LastActivityDate: 2014-09-24T11:04:56.943Z
Answers.UserDisplayName: Fred Carlsen
Body: <p>I am planning to create a <a href="http://indiewebcamp.com/micropub" rel="nofollow">micropub</a> plugin so that any micropub client can post to craft, particularly useful for automatic data logging and mobile clients. But I am trying to work out the best way to authenticate.</p>
  
  <p>I have read through the <a href="https://buildwithcraft.com/classreference/etc/users/UserIdentity" rel="nofollow">UserIdentity</a> docs but I was wondering if anybody has an examples of how to use it correctly?</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-09-24T09:48:33.100Z
Comments.Text: I should note that micropub uses IndieAuth (similar to OpenID) and therefore the plugin will not have the password to authenticate with.
Comments.UserDisplayName: Shane Hudson
Tags: <authentication>
Title: What is the correct way to use UserIdentity?
ThreadText: # What is the correct way to use UserIdentity?
  
  (Asked by: username_0 on 2014-09-24)
  
  I am planning to create a [micropub](http://indiewebcamp.com/micropub) plugin so that any micropub client can post to craft, particularly useful for automatic data logging and mobile clients. But I am trying to work out the best way to authenticate.
  
  I have read through the [UserIdentity](https://buildwithcraft.com/classreference/etc/users/UserIdentity) docs but I was wondering if anybody has an examples of how to use it correctly?
  
  **Tags:** authentication
  
  > **Comments:**
  > **username_0**: I should note that micropub uses IndieAuth (similar to OpenID) and therefore the plugin will not have the password to authenticate with.  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2014-09-24. Score: 4 | Accepted answer
  
  The basic user identity relies on login and password, so you will have to create your own class to represent an identity based on something else, like a token for example:
  
  ```
  <?php
  
  namespace Craft;
  
  class TokenIdentity extends UserIdentity
  {
      private $_id;
      public $token;
  
      public function __construct($token)
      {
          $this->token = $token;
      }
  
      public function authenticate()
      {
          $socialUser = craft()->social->getUserByEncodedToken($this->token);
  
          if($socialUser) {
              $this->_id = $socialUser->user->id;
              $this->username = $socialUser->user->username;
              $this->errorCode = static::ERROR_NONE;
  
              return true;
          } else {
              return false;
          }
      }
  
      public function getId()
      {
          return $this->_id;
      }
  }
  
  ```
  
  Then you'll need to create your own user session service to be able to authenticate the user (with a token for example):
  
  ```
  <?php
  
  namespace Craft;
  
  class Social_UserSessionService extends UserSessionService {
  
      private $_identity;
      public $allowAutoLogin = true;
  
      public function init()
      {
          $this->setStateKeyPrefix(md5('Yii.Craft\UserSessionService.'.craft()->getId()));
  
          parent::init();
      }
  
      public function login(Oauth_TokenModel $token)
      {
          $rememberMe = true;
  
          $this->_identity = new TokenIdentity($token->encodedToken);
          $this->_identity->authenticate();
  
          // Was the login successful?
          if ($this->_identity->errorCode == TokenIdentity::ERROR_NONE)
          {
              // Get how long this session is supposed to last.
  
              $this->authTimeout = craft()->config->getUserSessionDuration($rememberMe);
  
              $id = $this->_identity->getId();
  
              $user = craft()->users->getUserById($id);
  
              $states = $this->_identity->getPersistentStates();
  
              // Run any before login logic.
              if ($this->beforeLogin($id, $states, false))
              {
                  // Fire an 'onBeforeLogin' event
                  $this->onBeforeLogin(new Event($this, array(
                      'username'      => $user->username,
                  )));
  
                  $this->changeIdentity($id, $this->_identity->getName(), $states);
  
                  // Fire an 'onLogin' event
                  $this->onLogin(new Event($this, array(
                      'username'      => $user->username,
                  )));
  
                  if ($this->authTimeout)
                  {
                      if ($this->allowAutoLogin)
                      {
                          if ($user)
                          {
                              // Save the necessary info to the identity cookie.
                              $sessionToken = StringHelper::UUID();
                              $hashedToken = craft()->security->hashData(base64_encode(serialize($sessionToken)));
                              $uid = craft()->users->handleSuccessfulLogin($user, $hashedToken);
  
                              $data = array(
                                  $this->getName(),
                                  $sessionToken,
                                  $uid,
                                  ($rememberMe ? 1 : 0),
                                  craft()->request->getUserAgent(),
                                  $this->saveIdentityStates(),
                              );
  
                              $this->saveCookie('', $data, $this->authTimeout);
                          }
                          else
                          {
                              throw new Exception(Craft::t('Could not find a user with Id of {userId}.', array('{userId}' => $this->getId())));
                          }
                      }
                      else
                      {
                          throw new Exception(Craft::t('{class}.allowAutoLogin must be set true in order to use cookie-based authentication.', array('{class}' => get_class($this))));
                      }
                  }
  
                  $this->afterLogin(false);
              }
  
              return !$this->getIsGuest();
          }
  
          Craft::log('Tried to log in unsuccessfully.', LogLevel::Warning);
          return false;
      }
  }
  
  ```
  
  This code comes from a plugin which is still under development so don't take for granted it's all secure or the best way to achieve this, but hopefully it will help you get started !
  
  > **Comments:**
  > **username_0**: I was planning to use tokens, so this looks like the perfect place to start. Thanks!  
  
  ---
  
  ### Answer by username_2 on 2014-09-24. Score: 2
  
  What about setting up a relation between your CustomUserAuthModel and the UserModel, check if everything is alright through your plugin with IndieAuth, and then login, through UserSessionService->impersonate()?
  
  ```
  The new user session will only last as long as the browser session remains active; no identity cookie will be * created.
  
  ```
  
  Not sure if that will work for you, but might be worth a try?
  
  > **Comments:**
  > **username_0**: I didn't know about impersonate, that could be quite useful thanks!  
  
  ---
  
  