Jump to content

Problem retrieving currently logged in member via API.


Go to solution Solved by Stuart Silvester,

Recommended Posts

A bit of API testing first to know it's working:

\IPS\Member::load('some_username', 'name'); //works as expected, I get the user
\IPS\Member::load($member_id, 'member_id'); //works as expected, I get the user

Authenticating a user via the API:
$session = \IPS\Session\Front::i();
$session->setMember($member);
$member = \IPS\Member::load('username', 'name');
$device = \IPS\Member\Device::loadOrCreate($member);
$device->anonymous = false;
$device->updateAfterAuthentication($rememberMe, null);

$member->memberSync('onLogin');
$member->profileSync();

At this point, if I visit the forum, I see that I am logged in as the user so the authentication works.
But, if I do a $member = \IPS\Member::loggedIn(); I get guest, regardless if I do the call right after authentication or after page refresh.

Any idea on what am I missing here?
 

Link to comment
Share on other sites

here is the class that communicates with the InvisionAPI. It has been curated to avoid any sensitive info exposed

 

<?php
/**
 * Here is the full class that communicates with the InvisionAPI
 * 
 */
class InvisionAPI {

    private static $instance;

    public static function getInstance() {
        if (self::$instance == null) {
            self::$instance = new InvisionAPI();
        }
        return self::$instance;
    }

    private $settings;
    private $database;
    private $session;

    public function __construct() {
        $this->refreshSession();

        $this->session  = \IPS\Session\Front::i();
        $this->database = \IPS\Db::i();
        $this->settings = \IPS\Settings::i();
    }

    /**
     * Refreshes our IPS session, if we ever had one.
     * Required if for some reason our session has timed out and we have yet to revisit the suite.
     */
    public function refreshSession() {
        $this->requireIPS();
        \IPS\Session\Front::i();
    }

    public function isGuest($member) {
        return $member->member_group_id == $this->settings->guest_group;
    }

    /**
     * Returns the current logged in user
     * This method is called when I access after login form, it always returns Guest!
     * @return null
     */
    public function getCachedMember() {
        $this->refreshSession();
        $member = \IPS\Member::loggedIn();
       
        if ($this->isGuest($member)) {
            return null;
        }
        return new InvisionMember($member);
    }

    public function loadMember($username) {
        $member = \IPS\Member::load($username, 'name');
        if ($this->isGuest($member)) {
            return null;
        }

        return $member;
    }

    /**
     * This returns true when user/pass is OK so I know it works!
     */
    public function login($username, $password, $rememberMe = false) {
        $member = $this->loadMember($username);
        if ($member == null) {
            return null;
        }
        
        if (!$this->verifyPassword($member, $password)) {
            return false;
        }
        
        $this->setSession($member, $rememberMe);
        return true;
    }

    public function logout() {
        $member = $this->getCachedMember();

        if ($member == null) {
            return; // We are already logged out
        }

        session_destroy();

        \IPS\Request::i()->clearLoginCookies();
        $member->memberSync('onLogout', array(\IPS\Http\Url::internal('')));
    }

    /**
     * Sets the user session after use has been verified.
     * @param $member
     * @param $rememberMe
     */
    public function setSession($member, $rememberMe) {
        $this->session->setMember($member);

        $device = \IPS\Member\Device::loadOrCreate($member);

        $member->last_visit = $member->last_activity;
        $member->save();

        $device->anonymous = false;
        $device->updateAfterAuthentication($rememberMe, null);

        $member->memberSync('onLogin');
        $member->profileSync();
        
        /**
         * If I do a test here, it fails, I get guest!
         * $member = \IPS\Member::loggedIn();
         */
    }

 
    public function verifyPassword($member, $password) {
        return password_verify($password, $member->members_pass_hash) === true;
    }


    private function requireIPS() {
      
        require_once FORUM_PATH . 'init.php';
    }

}

 

Link to comment
Share on other sites

  • 3 weeks later...
  • Solution

What's going to be happening here is that \IPS\Member::$loggedInMember will already be set to a guest by \IPS\Session\Front::read(), since you're overriding that and setting a member after that has ran, you'll also need to reset the cached logged in member after calling `$this->session->setMember($member)`

\IPS\Member::$loggedInMember = NULL;

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...