ilch Forum » Ilch CMS 2.X » Module und Modifikationen » Wargaming API Login

Geschlossen
  1. #1
    User Pic
    MonkeyOnKeyboard Moderator
    Registriert seit
    10.02.2014
    Beitrge
    414
    Beitragswertungen
    19 Beitragspunkte
    Servus,

    ich habe vor einiger Zeit eine API Anmeldung mit Wargaming ( WorldOfTanks ) gebaut. als Grundlage dafür habe ich das Twitterauth Modul von dustiii genommen.

    Soweit funktioniert die Anmeldung wie sie soll.

    Hier mal die AuthPHP

    <?php
    
    namespace Modules\wargamingauth\Controllers;
    
    use Ilch\Controller\Frontend;
    use Modules\wargamingauth\Libs\wargamingOAuth;
    use Modules\wargamingauth\Mappers\DbLog;
    use Modules\User\Mappers\AuthProvider;
    use Modules\User\Mappers\AuthToken as AuthTokenMapper;
    use Modules\Phonebook\Models\Book;
    use Modules\Phonebook\Mappers\Phonebook as PhonebookMapper;
    use Modules\User\Mappers\User as UserMapper;
    use Modules\User\Mappers\Group;
    use Modules\User\Models\AuthProviderUser;
    use Modules\User\Models\AuthToken as AuthTokenModel;
    use Modules\User\Models\User;
    use Modules\User\Service\Password as PasswordService;
    use Ilch\Validation;
    use Modules\wargamingauth\Mappers\Wargaming as WargamingMapper;
    use Modules\wargamingauth\Models\Wargaming as WargamingModel;
    use Modules\wargamingauth\Mappers\User as WGUserMapper;
    use Modules\wargamingauth\Models\User as WGUserModel;
    
    class Auth extends Frontend
    {
        /**
         * @var DbLog instance
         */
        protected $dbLog;
    
        /**
         * Renders the register form.
         */
        public function registAction()
        {
            $oauth = array_dot($_SESSION, 'wargamingauth.login');
            $groupMapper = new Group();
            $userGroup = $groupMapper->getGroupByName($oauth['clantag']);
            //var_dump($userGroup);
            //die();
            if (! array_dot($_SESSION, 'wargamingauth.login') || array_dot($_SESSION, 'wargamingauth.login.expires') < time() || !$userGroup ) {
                $this->addMessage('wargamingauth.logindenied', 'danger');
                $this->redirect(['module' => 'user', 'controller' => 'login', 'action' => 'index']);
            }
    
    
            $this->getView()->set('rules', $this->getConfig()->get('regist_rules'));
            $this->getView()->set('user', $oauth);
        }
    
        /**
         * Saves the new user to the database.
         */
        public function saveAction()
        {
            if (!$this->getRequest()->isPost()) {
                $this->addMessage('badRequest');
                $this->redirect('/');
            }
    
            if (! array_dot($_SESSION, 'wargamingauth.login') || array_dot($_SESSION, 'wargamingauth.login.expires') < time()) {
                $this->addMessage('badRequest');
                $this->redirect(['module' => 'user', 'controller' => 'login', 'action' => 'index']);
            }
    
            $input = [
                'userName' => trim($this->getRequest()->getPost('userName')),
                'email' => trim($this->getRequest()->getPost('email')),
                'phonenumber' => trim($this->getRequest()->getPost('phonenumber')),
            ];
    
            $validation = Validation::create($input, [
                'userName' => 'required|unique:users,name',
                'email' => 'required|email|unique:users,email',
                'phonenumber' => 'required',
            ]);
            
            
            $oauth = array_dot($_SESSION, 'wargamingauth.login');
            
            
            if ($validation->isValid()) {
                // register user
                $registMapper = new UserMapper();
                $groupMapper = new Group();
                $userGroup = $groupMapper->getGroupByName($oauth['clantag']);
                $currentDate = new \Ilch\Date();
    
                $user = (new User())
                    ->setName($input['userName'])
                    ->setPassword((new PasswordService())->hash(PasswordService::generateSecurePassword(32)))
                    ->setEmail($input['email'])
                    ->setDateCreated($currentDate->format('Y-m-d H:i:s', true))
                    ->addGroup($userGroup)
                    ->setDateConfirmed($currentDate->format('Y-m-d H:i:s', true));
    
                $userId = $registMapper->save($user);
               
                $phoneBookMapper = new PhonebookMapper();
                            
                $phonebook = (new Book())
                ->setUser_id($userId)
                ->setClantag($oauth['clantag'])
                    ->setPhonenumber($input['phonenumber']);
                
               $phonenumberentry = $phoneBookMapper->save($phonebook);          
                    
    
                
    
                $authProviderUser = (new AuthProviderUser())
                    ->setIdentifier($oauth['user_id'])
                    ->setProvider('wargaming')
                    ->setOauthToken($oauth['oauth_token'])
                    ->setOauthTokenSecret($oauth['oauth_token_secret'])
                    ->setScreenName($oauth['screen_name'])
                    ->setUserId($userId);
    
                $link = (new AuthProvider())->linkProviderWithUser($authProviderUser);
    
                if ($link === true) {
                    $_SESSION['user_id'] = $userId;
                    $this->addMessage('wargamingauth.linksuccess');
                    $this->redirect(['module' => 'user', 'controller' => 'panel', 'action' => 'index']);
                }
    
                $this->addMessage('wargamingauth.linkfailed', 'danger');
                $this->redirect('/');
            }
    
            $this->addMessage($validation->getErrorBag()->getErrorMessages(), 'danger', true);
            $this->redirect()
                ->withInput()
                ->withErrors($validation->getErrorBag())
                ->to(['action' => 'regist']);
        }
    
        public function unlinkAction()
        {
            if (loggedIn()) {
                if ($this->getRequest()->isPost()) {
                    $authProvider = new AuthProvider();
                    $res = $authProvider->unlinkUser('wargaming', currentUser()->getId());
    
                    if ($res > 0) {
                        $this->addMessage('wargamingauth.unlinkedsuccessfully');
                        $this->redirect(['module' => 'user', 'controller' => 'panel', 'action' => 'providers']);
                    }
    
                    $this->addMessage('wargamingauth.couldnotunlink', 'danger');
                    $this->redirect('/');
                }
    
                $this->addMessage('wargamingauth.badrequest', 'danger');
                $this->redirect('/');
            }
    
            $this->addMessage('wargamingauth.notauthenticated', 'danger');
            $this->redirect('/');
        }
    
        /**
         * Initialize authentication.
         */
        public function indexAction()
        {
            $callbackUrl = $this->getLayout()->getUrl([
                'module' => 'wargamingauth',
                'controller' => 'auth',
                'action' => 'callback',
            ]);
    
            $auth = new wargamingOAuth(
                $this->getConfig()->get('wargamingauth_consumer_key'),
                'popup',
                1,
                null,
                $callbackUrl
            );
    
            try {
    
                $auth->obtainTokens();
    
    
    //        var_dump($auth->getAuthenticationEndpoint());
    //        die();
    
                $this->redirect($auth->getAuthenticationEndpoint()); // wargaming openid
            } catch (\Exception $e) {
                $this->addMessage('wargamingauth.authenticationfailure', 'danger');
    
                if (loggedIn()) {
                    $this->redirect(['module' => 'user', 'controller' => 'panel', 'action' => 'providers']);
                }
    
                $this->redirect(['module' => 'user', 'controller' => 'login', 'action' => 'index']);
            }
        }
    
        /**
         * Callback action.
         */
        public function callbackAction()
        {
            //var_dump($_GET);
            //die();
    
            $auth = new wargamingOAuth(
                $this->getConfig()->get('wargamingauth_consumer_key')
            );
    
            try {
     
            //var_dump($this->getRequest());
            //die();
                $auth->handleCallback($this->getRequest());
    
            //var_dump($auth->getToken() . '<br>' . $auth->getAccount_id() . '<br>' . $auth->getExpires_at() . '<br>');
            $auth->get_clan_id();
            $auth->get_memberData();
            $auth->get_clanData();
            //var_dump($auth->getClantag() . '<br>' . $auth->getClan_id() . '<br>' . $auth->getToken() . '<br>'. $auth->getTreasury(). '<br>' );
            //die();
            
                
    //            $auth->convertTokens();
    
                
                
                $wargamingUser = array(
                  'user_id' => $auth->getAccount_id(),
                  'oauth_token' => $auth->getToken(),
                  'screen_name' => $auth->getAccount_name(),
                  'oauth_token_user' => null,
                  'clantag' => $auth->getClantag(),
                  'clan_id' => $auth->getClan_id(), 
                  'role' => $auth->getRole(),
                  'expires_at' => $auth->getExpires_at(),
                  'treasury' => $auth->getTreasury()  
                );
    
                $authProvider = new AuthProvider();
                $existingLink = $authProvider->providerAccountIsLinked('wargaming', $wargamingUser['user_id']);
    
                $_SESSION['clantag'] = $wargamingUser['clantag'];
                $_SESSION['account_name'] = $wargamingUser['screen_name'];
                $_SESSION['account_id'] = $wargamingUser['user_id'];
                $_SESSION['role'] = $wargamingUser['role'];
                
                
                if (loggedIn()) {
                    if ($authProvider->hasProviderLinked('wargaming', currentUser()->getId())) {
                        $this->dbLog()->info(
                            "User " . currentUser()->getName() . " had provider already linked.",
                            [
                                'userId' => currentUser()->getId(),
                                'userName' => currentUser()->getName(),
                                'wargamingAccount' => $wargamingUser
                            ]
                        );
    
    
                        
                        $this->addMessage('providerAlreadyLinked', 'danger');
                        $this->redirect(['module' => 'user', 'controller' => 'panel', 'action' => 'providers']);
                    }
    
                    if ($existingLink === true) {
                        $this->dbLog()->info(
                            "User " . currentUser()->getName() . " tried to link an already linked wargaming account.",
                            [
                                'userId' => currentUser()->getId(),
                                'userName' => currentUser()->getName(),
                                'wargamingAccount' => $wargamingUser
                            ]
                        );
    
                        $this->addMessage('accountAlreadyLinkedToDifferentUser', 'danger');
                        $this->redirect(['module' => 'user', 'controller' => 'panel', 'action' => 'providers']);
                    }
    
                    $authProviderUser = (new AuthProviderUser())
                        ->setIdentifier($wargamingUser['user_id'])
                        ->setProvider('wargaming')
                        ->setOauthToken($wargamingUser['oauth_token'])
                        ->setOauthTokenSecret($wargamingUser['oauth_token_user'])
                        ->setScreenName($wargamingUser['screen_name'])
                        ->setUserId(currentUser()->getId());
    
                    $link = $authProvider->linkProviderWithUser($authProviderUser);
    
                    if ($link === true) {
                        $this->dbLog()->info(
                            "User " . currentUser()->getName() . " has linked a wargaming account.",
                            [
                                'userId' => currentUser()->getId(),
                                'userName' => currentUser()->getName(),
                                'wargamingAccount' => $wargamingUser
                            ]
                        );
    
                        $this->addMessage('wargamingauth.linksuccess');
                        $this->redirect(['module' => 'user', 'controller' => 'panel', 'action' => 'providers']);
                    }
    
                    $this->dbLog()->error(
                        "User " . currentUser()->getName() . " could not link his wargaming account.",
                        [
                            'userId' => currentUser()->getId(),
                            'userName' => currentUser()->getName(),
                            'wargamingAccount' => $wargamingUser
                        ]
                    );
    
                    $this->addMessage('linkFailed', 'danger');
                    $this->redirect(['module' => 'user', 'controller' => 'panel', 'action' => 'providers']);
                }
    
                if ($existingLink === true) {
                    $userId = $authProvider->getUserIdByProvider('wargaming', $wargamingUser['user_id']);
    
                    if (is_null($userId)) {
                        $this->addMessage('couldNotFindRequestedUser');
                        $this->redirect(['module' => 'user', 'controller' => 'login', 'action' => 'index']);
                    }
    
                    /** Test Update Username and Screenname
                     * 
                     * @var \Modules\wargamingauth\Mappers\User $wgusermapper
                     */
                    
                    $wgusermapper = new WGUserMapper();
                    if ($_SESSION['account_name'] != $wgusermapper->getNameById($userId)->getName() AND $wgusermapper->getScreen_nameByUser_Id($userId)->getScreen_name()){
                        $UserModel = new WGUserModel();
                        
                        $UserModel->setUser_id($userId)
                        ->setScreen_name($_SESSION['account_name']);
                        $wgusermapper->updateScreen_name($UserModel);
                        
                        $UserModel->setId($userId)
                        ->setName($_SESSION['account_name']);
                        $wgusermapper->updateName($UserModel);
                        
                    }
                    
                        $authTokenModel = new AuthTokenModel();
                        
                        // 9 bytes of random data (base64 encoded to 12 characters) for the selector.
                        // This provides 72 bits of keyspace and therefore 236 bits of collision resistance (birthday attacks)
                        $authTokenModel->setSelector(base64_encode(openssl_random_pseudo_bytes(9)));
                        // 33 bytes (264 bits) of randomness for the actual authenticator. This should be unpredictable in all practical scenarios.
                        $authenticator = openssl_random_pseudo_bytes(33);
                        // SHA256 hash of the authenticator. This mitigates the risk of user impersonation following information leaks.
                        $authTokenModel->setToken(hash('sha256', $authenticator));
                        $authTokenModel->setUserid($userId);
                        $authTokenModel->setExpires(date('Y-m-d\TH:i:s', strtotime( '+1 day' ) ));
                        
                        setcookie('remember', $authTokenModel->getSelector().':'.base64_encode($authenticator), strtotime( '+1 day' ), '/', $_SERVER['SERVER_NAME'], (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'),  true);
                        setcookie('clantag', $_SESSION['clantag'], strtotime( '+1 day' ), '/', $_SERVER['SERVER_NAME'], (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'),  true);
                        setcookie('account_name', $_SESSION['account_name'], strtotime( '+1 day' ), '/', $_SERVER['SERVER_NAME'], (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'),  true);
                        setcookie('account_id', $_SESSION['account_id'], strtotime( '+1 day' ), '/', $_SERVER['SERVER_NAME'], (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'),  true);
                        setcookie('role', $_SESSION['role'], strtotime( '+1 day' ), '/', $_SERVER['SERVER_NAME'], (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'),  true);
                        
                        $authTokenMapper = new AuthTokenMapper();
                        $authTokenMapper->addAuthToken($authTokenModel);
                   
                    
                    
                    $_SESSION['user_id'] = $userId;
                    
                    
                    // treasury in db
                    
                    $WargamingMapper = new WargamingMapper();
                    $model = new WargamingModel();
                    
                    $model->setClantag($wargamingUser['clantag']);
                    $model->setClan_id($wargamingUser['clan_id']);
                    $model->setTreasury($wargamingUser['treasury']);;
                    $WargamingMapper->save($model);
                    
                    
                    $this->addMessage('wargamingauth.loginsuccess');
                    $this->redirect('/');
                }
    
                if ($existingLink === false && ! loggedIn() && ! $this->getConfig()->get('regist_accept')) {
                    $this->addMessage('wargamingauth.messages.registrationNotAllowed', 'danger');
                    $this->redirect(['module' => 'user', 'controller' => 'login', 'action' => 'index']);
                }
    
                array_dot_set($_SESSION, 'wargamingauth.login', $wargamingUser);
                array_dot_set($_SESSION, 'wargamingauth.login.expires', strtotime('+5 minutes'));
                //array_dot_set($_SESSION, 'wargamingauth.login.expires', $wargamingUser['expires_at']);
    
                $this->redirect(['action' => 'regist']);
    
            } catch (\Exception $e) {
                $this->addMessage('wargamingauth.authenticationfailure', 'danger');
    
                if (loggedIn()) {
                    $this->redirect(['module' => 'user', 'controller' => 'panel', 'action' => 'providers']);
                } else {
                    $this->redirect(['module' => 'user', 'controller' => 'login', 'action' => 'index']);
                }
            }
        }
    
        /**
         * @return DbLog
         */
        protected function dbLog()
        {
            if ($this->dbLog instanceof DbLog) {
                return $this->dbLog;
            }
    
            return $this->dbLog = new DbLog();
        }
    }



    Leider habe ich diverse Schwierigkeiten.

    1. Im Moment Speichere ich die Wargaming API Wehrte in eine Session und dann anschließend in einen Cookie. Sie CallBack Function

    -> Ist es möglich auf soviele Coockies zu verzichten. die Wehrte virtuel über die Funktion
    register->set
    und
    register->get
    zu nutzen? Oder wofür sind diese funktionen Gedacht.

    2. Mir ist aufgefallen, dass im Ilch keine Prüfung drin ist, wenn Cookie Abgelaufen, melde User ab.

    -> Hat mehrere Gründe. Da ich im Moment ja die Daten, wie Account_Name, Account_id, role und clantag im Cookie habe. Die Ablauffrist auf +1day steht. und ich diese Daten Intern für verschiedene Module nutze und brauche.

    Nun ist es so. Member xyz hat sich vor 23 Stunden angemeldet. nun kommt er wieder auf die Seite, ist noch angemeldet durch remember me cookie mit den anderen. nun passiert es. die cookies laufen aus. und er will was intern mit den wg daten machen. Sei es Im Recruting Modul oder im Away Modul, welches ich erweitert habe.

    Cookies sind weg. und was bleibt sind dann fehler....

    Gibt es eine Möglichkeit eine Funktion im Ilch zu implimentieren, welche prüft ob cookie abgelaufewn,m wenn ja.. session destroy und logout?


    verwendete ilch Version: 2.1.x

    betroffene Homepage: www.r1sing.de
    0 Mitglieder finden den Beitrag gut.
  2. #2
    User Pic
    blackcoder Entwickler
    Registriert seit
    22.05.2014
    Beitrge
    2.005
    Beitragswertungen
    320 Beitragspunkte
    Als Antwort auf deine PN:

    1) Natürlich kann man auch mehrere Werte in einem Cookie speichern.
    Dafür könntest du z.B. folgende Funktionen nutzen:
    www.php.net/manual/de/function.explode.php
    www.php.net/manual/de/function.implode.php

    2) Das ist nicht zwangsläufig die Aufgabe von Ilch, sondern die des Browsers. Wenn du nicht willst, dass deine Cookies ablaufen, dann müsstest du diese neu setzen bzw. bei der Wargaming-API neu "authentifizieren", wenn der Benutzer die Seite wieder besucht.

    Nebenbei: Hat der Benutzer bei deiner Wargaming-API vorher zugestimmt, dass er den "Angemeldet bleiben"-Cookie (remember) gesetzt haben möchte oder setzt du diesen einfach? Es könnte sein, dass er diesen gar nicht gesetzt oder einen vorhandenen Cookie durch deinen mit anderer Gültigkeitsdauer überschrieben haben möchte.


    Zuletzt modifiziert von blackcoder am 31.05.2019 - 16:07:32
    0 Mitglieder finden den Beitrag gut.
Geschlossen

Zurck zu Module und Modifikationen

Optionen: Bei einer Antwort zu diesem Thema eine eMail erhalten