Регистрация и авторизация пользователя на сайте — одним кликом — через кастомную кнопку Facebook. 2017

в 9:47, , рубрики: 2017, codeigniter, CodeIgniter 3, Facebook API, Facebook OAuth 2, facebook sdk, fb2, jquery, php, апрель 2017

Итак, начал я разрабатывать один проект по фану. Основная идея проекта проста: площадка, где все могут ставить на всё что угодно, заключать пари, сделки и БЕЗ каких либо ограничений. Развлекательный проект по сути своей.

Ну и конечно стал вопрос Удобной авторизации пользователей с наименьшим «трением». Подумав немного, я выбрал авторизацию через Facebook, но думаю, на этом я не остановлюсь и вы прочтете ещё несколько статей, с авторизацией через Google Acc, VK и Tweet.

image
Итак к делу! В интернете я нашел несколько тем, которые описывают вопрос авторизации, некоторая информация мне помогла, но я не нашел ни одной, которая бы решила поставленную мной задачу, поэтому, завершив задачу я и решил написать эту статью.

СДЕЛАНО: Регистрация пользователя в БД и его авторизация на сайте одним нажатием Кастомной кнопки (любая картинка на ваш вкус)

1. РЕГИСТРАЦИЯ ПРИЛОЖЕНИЯ В ФБ:

а. https://developers.facebook.com/apps/
б. Регистрируем приложение, прописываем адрес вашего сайта, страницы принятия данных для ответа, и многое другое. Интерфейс очень дружелюбный, фэйсбук нас любит. Поэтому рассписывать всё и вся я не буду. Оттуда нам нужно будет ID приложения и адрес сайта.

2. ФРОНТ ЭНД:

Привожу полный рабочий пример со своего сайта. По клику на ссылку вызывается функция: «fb_login()», функция сначала проверяет «а залогинен ли пользователь в фэйсбуке?» если ДА, берет его ID и отправляет аяксом в БэкЭнд, если НЕТ, то вызывает форму для входа в Фэйсбук аккаунт.

fb_login() — инициирует общение с ФБ
handle_fb_data() — занимается получением и пересылкой полученных из ФБ данных пользователя в БэкЭнд

<a class="fb_login_btn" onclick="fb_login();return false;"><img src="/image/fb_login.png" border="0" alt=""></a>

<script>
    function handle_fb_data(response){
        FB.api('/me', function(response) {
            console.log('Successful login for: ' + response.name);
            console.log('Прилитело из ФБ: '+JSON.stringify(response));
//            alert('Прилитело из ФБ: '+JSON.stringify(response));

            $.ajax({
                type: 'post',
                url: '/do/reg/fb',
                data: response,
                success: function(msg) {
                    console.log(msg);
                    if ((msg=='зарегались')||(msg=='залогинились')){window.location.reload();}
                },
                error: function(){}
            })
        });
    }

    function fb_login(){
        FB.getLoginStatus(function(response) {
            if (response.authResponse) {
                console.log('Welcome!  Fetching your information.... ');
                handle_fb_data(response);
            } else {
                console.log('Юзер был не залогинен в самом ФБ, запускаем окно логинизирования');
                FB.login(function(response){
                    if (response.authResponse) {
                        console.log('Welcome!  Fetching your information.... ');
                        handle_fb_data(response);
                    } else {
                        console.log('Походу пользователь передумал логиниться через ФБ');
                    }
                });
            }
        }, {
            scope: 'email,id'
        });
    }

    window.fbAsyncInit = function() {
        FB.init({
            appId      : '{ТУТ ВСТАВЬТЕ ID ПРИЛОЖЕНИЯ}',
            cookie     : true,  // enable cookies to allow the server to access
            // the session
            xfbml      : true,  // parse social plugins on this page
            version    : 'v2.8' // use graph api version 2.8
        });
    };
    // Load the SDK asynchronously
    (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) return;
        js = d.createElement(s); js.id = id;
        js.src = "//connect.facebook.net/en_US/sdk.js";
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
</script>

Ну собственно по фронтэнду всё, теперь рассмотрим БэкЭнд.

3. БЭК ЭНД

    public function fb(){
        if (($this->session->userdata('logged_in') != true) ){
//       1. Не делаем ничего, если пользователь УЖЕ залогинен.
//       2. Если нет, то Проверим, есть ли у нас в БД юзер с таким FB_ID
//        если есть, то залогинем его
//       3. Если пользователя в базе нет, то сначала его зарегаем и сразу залогинем

//       Итак, вытаскиваем из базы всё что есть по данному пользователю и заносим всё в его сессию, т.е. "логинем"            
            $query = $this->db->get_where('users', array('fb_id' => $_POST['id']));

            if ($query->num_rows() > 0) {
                foreach ($query->row_array() as $key => $value) {
                    $userdata[$key] = $value;
                }
                $userdata["logged_in"] = true;

                //проверяем, есть ли у пользователя в сессии информация по какой-либо его сделке, если есть, добавляем пользователя в сделку

                if ($this->session->userdata('bet_code_last') != false) {
                    $data = array(
                        'start_user_id' => $userdata['id']
                    );
                    $this->db->where('bet_code', $this->session->userdata('bet_code_last'));
                    $this->db->update('bet', $data);
                    $this->session->sess_destroy();
                }

                $this->session->set_userdata($userdata);
                echo 'залогинились';
            } else {
                $data = array(
                    'fb_id'     => $_POST['id'],
                    'lang'     => 'en',
                    'name'     => $_POST['name'],
                );

//                предполагаем, что если имя пользователя содежит русские символы, то русский язык интерфейса ему будет более удобен
                if( preg_match('/[ёа-я]/i', $_POST['name']) ){$data['lang']='ru';}
                $this->db->insert('users', $data);

// строчкой выше зарегали его в базе, а стройкой ниже залогинили пользователя ;)
                $data["logged_in"] = true;
                $this->session->set_userdata($data);
             echo 'зарегались';
            }
        }else{echo 'уже был залогинен';}
    }

В PHP коде используются функции обращения в БД от фрэймворка Codeigniter. Ну в общем весь процесс я описал, надеюсь, что весьма понятно и доступно.

Примечания:

1. Потом и кровью сам додумал, что лучше будет сначала проверять статус, а потом вызывать форму логина (на фронтэнде), чего не было не в одном из описаний в явном виде.

2. После того как данные занесены в сессию, страница все ещё не обновлена, поэтому я её обновляю вот этой строкой, в те моменты, когда БэкЭнд подтверждает что сдела всё, что надо:
if ((msg=='зарегались')||(msg=='залогинились')){window.location.reload();}

Спасибо за внимание!

Автор: wmag

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js