Integrasi Single Sign On OpenID pada Website berbasis PHP


OpenID adalah sebuah layanan identitas terpusat yang memungkinkan seseorang cukup mempunyai satu identitas untuk bisa mengakses berbagai macam website. Dengan mengintegrasikan aplikasi ini akan memudahkan user yang akan login pada website kita karena ia hanya perlu cukup mengingat satu account saja. Hingga saat ini OpenID sudah di dukung oleh website-webiste besar seperti Google, Yahoo, WordPress, VeriSign, AOL dll.

Pada OpenID terdapat dua tipe OpenID, yaitu OpenID sebagai identitiy provider dan OpenID sebagai client. OpenID sebagai identity provider adalah applikasi yang memberikan data user yang akan login kepada website yang menjadi OpenID client. Beberapa website yang sudah disebutkan di atas adalah website yang bertindak sebagai identity provider. Sedangkan contoh website yang menjadi OpenID client adalah Facebook, Sourceforge dll.

Dalam panduan berikut kita akan membuat website kita bertindak sebagai OpenID client side. Yang perlu diperhatikan adalah, OpenID menggunakan alamat url sebagai identitas user. Sebagai contoh Worpdress menggunakan http://nama_anda.wordpress.com/, Yahoo menggunakan http://me.yahoo.com/nama_anda dan Google menggunakan Blogspot sebagai OpenID url seperti http://nama_anda.blogspot.com.

Untuk mendapatkan library PHP OpenID Anda bisa mendownload di openid Libraries.

Dalam panduan ini penulis menggunakan library yang dibuat oleh JanRain openidenabled.com.

Pertama-tama kita akan membuat sebuah halaman index.php yang berisi form login untuk user. Di dalam halaman ini juga dilakukan proses otentifikasi data user. Berikut adalah source codenya:

<?php
require_once "common.php";
session_start();
$errors = null;

if( isset($_POST['submit']) ){

    $openid = $_POST['openid_identifier'];

    if(empty($openid))
        $errors[] = 'Your OpenID Empty.';

    if(!isset($errors)){
        $consumer = getConsumer();
        // Mulai proses otentivikasi OpenID.
        $auth_request = $consumer->begin($openid);
    }

    // Tampilkan error jika otentvikasi gagal.
    if (!$auth_request) {
        $errors[] = 'Authentication error; not a valid OpenID.';
    }

    if(!isset($errors)){
        //Inisial data user yang akan di minta ke OpenID server
        $sreg_request = Auth_OpenID_SRegRequest::build(
                                         // Required
                                         array('nickname'),
                                         // Optional
                                         array('fullname', 'email'));

        if ($sreg_request) {
            $auth_request->addExtension($sreg_request);
        }
    }

    // Redirect user ke OpenID server.
    if(!isset($errors)){
        if ($auth_request->shouldSendRedirect()) {
            $redirect_url = $auth_request->redirectURL(getTrustRoot(),
                                                       getReturnTo());

            // Tampilkan error jika redirect gagal.
            if (Auth_OpenID::isFailure($redirect_url)) {
                $errors[] = 'Could not redirect to server: ' . $redirect_url->message;
            } else {
                // Send redirect.
                header("Location: ".$redirect_url);
            }
        } else {
            // Untuk OpenID 2.0 Generate html.
            $form_id = 'openid_message';
            $form_html = $auth_request->htmlMarkup(getTrustRoot(), getReturnTo(),
                                                   false, array('id' => $form_id));

            //tampilkan errror jika gagal generate html
            if (Auth_OpenID::isFailure($form_html)) {
                $errors[] = 'Could not redirect to server: ' . $form_html->message;
            } else {
                print $form_html;
                exit;
            }
        }
    }
}

if( isset($_SESSION['openid']) )
    header('Location:home.php?');
?>
<html>
<head><title>PHP OpenID</title></head>

<body>
<?php
if( isset($errors) ){
    foreach( $errors as $error){
        echo $error.'<br />';
    }
}
?>
<form method="post" action="">
 OpenID URL:
<input type="hidden" name="action" value="verify" />
<input type="text" name="openid_identifier" value="" />
<input type="submit" name="submit" value="Login" />
</form>
</div>
</body>
</html>

Setelah user mengisikan OpenID url dan melakukan submit, maka data akan diproses oleh OpenID library dan dikirimkan ke OpenID provider menggunakan curl atau fopen. Jika data yang diisikan oleh user valid, maka OpenID provide akan memberikan data respon. Selanjutnya, user akan diridirect ke OpenID provider untuk memberikan konfirmasi ke user untuk memberikan persetujuan pertukaran data antara OpenID provider dan OpenID client.

Jika user memberikan persetujuan, OpenID server akan meredirect user kembali ke OpenID client. Pada OpenID client kembali terjadi pertukaran data antara OpenID provider dan OpenID client untuk mendapatkan data user yang diminta oleh OpenID client.

Berikut adalah code untuk halaman finish_auth.php yang menerima respon dari OpenID server setelah user memberikan persetujuan.

<?php
require_once "common.php";
session_start();

function escape($thing) {
    return htmlentities($thing);
}

function run() {
    $consumer = getConsumer();

    // Complete the authentication process using the server's
    // response.
    $return_to = getReturnTo();
    $response = $consumer->complete($return_to);

    // Check the response status.
    if ($response->status == Auth_OpenID_CANCEL) {
        // This means the authentication was cancelled.
        exit('Verification cancelled.');
    }
    else if ($response->status == Auth_OpenID_FAILURE) {
        // Authentication failed; display the error message.
        exit('OpenID authentication failed: ' . $response->message);
    }
    else if ($response->status == Auth_OpenID_SUCCESS) {
        // This means the authentication succeeded; extract the
        // identity URL and Simple Registration data (if it was
        // returned).
        $openid = $response->getDisplayIdentifier();
        $esc_identity = escape($openid);

        $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
        $sreg = $sreg_resp->contents();
        do_login($esc_identity, $sreg);
    }
}

function do_login($openid, $sreg = null){
    session_start();
    $_SESSION['openid'] = $openid;
    header('Location:home.php?');
}

run();

?>

Kini user sudah berada pada halaman home.php yang itu berarti user sudah memiliki otoritas. Berikut adalah code dari file home.php:

<?php
session_start();
if(empty($_SESSION) || !isset($_SESSION) )
    header('Location:index.php');

if(isset($_GET['logout'])){
    session_destroy();
    header('Location:index.php');
}
else{
    $openid = $_SESSION['openid'];
?>
<html>
<head><title>Welcome <?php echo $openid;?></title></head>
<body>
    Selamat datang <?php echo $openid;?> <a href="?logout">Logout</a>
</body>
</html>
<?php
}
?>

Selain tiga file ini, kita juga membuthkan file common.php dan semua isi folder Auth yang bisa didapatkan dari JanRain PHP library.

Kini website Anda sudah terintegrasi dengan OpenID

Advertisements

Mengengembangkan Single Sign On System (SSO) menggunakan OAuth


OAuth merupakan sebuah protokol yang saat ini mulai banyak digunakan oleh penyedia layanan internet seperti Facebook, Yahoo, Twitter, Google dll. Protokol ini membantu sharing informasi dan sumberdaya pribadi seseorang dari suatu aplikasi ke aplikasi lainnya dengan cara yang lebih aman tanpa perlu user memberikan passwordnya. Untuk mendapatkan informasi ini, user terlebih dahulu harus memberikan izin kepada aplikasi pihak ketiga yang ingin mendapatkan informasi tentang dirinya.

OAuth 2.0 adalah pengembangan dari OAuth versi 1 yang dibuat dengan tujuan untuk menyederhanakan dan mempermudah proses alur pertukaran data. Walaupun demikian OAuth 2 sama sekali berbeda dengan OAuth versi 1 sehingga aplikasi yang baru mendukung versi 1 tidak lagi bisa digunakan. Provider yang masih menggunakan OAuth versi 1 diantaranya Yahoo, Google dan Twitter. Sedangkan yang sudah mendukung versi 2 adalah Facebook, Google (experimental) dan Github. Untuk selanjutnya pembahasan dalam artikel ini hanya menitikberatkan pada OAuth 2.0.

Dalam proses ini setidaknya terdapat dua aplikasi yang saling berinteraksi satu sama lain. Aplikasi yang menyediakan sumberdaya disebut OAuth Provider dan yang menerima disebut OAuth client.

Sebelum membahas lebih lanjut, mari kita lihat bagai mana protokol ini bekerja dengan menggunakan Facebook sebagai OAuth provider.

SSO umumnya digunakan pada suatu layanan yang memiliki banyak aplikasi yang masing-masing aplikasi ini berdiri sendiri. Sebagai contoh jika kita memberikan layanan blog dimana user bisa menggunakan layanan ini dengan cara memasukan username dan password, maka ketika kita memiliki layanan lain misalnya forum ada baiknya user yang ingin memanfaatkan layanan ini tidak perlu dimintakan password dan usernamenya lagi. Contoh dari layanan yang sudah menerapkan mekanisme SSO untuk semua layanannya adalah Google dan Yahoo. Silahkan buka dan login di http://www.google.com/. Setelah login silahkan buka tab baru di browser dan buka halaman http://goo.gl/. Sebagaimana Anda lihat, setelah berhasil login di halaman muka google.com kita juga bisa langsung menikmati layanan lainnya dari google tanpa perlu lagi memasukan username atau password.

Istilah pada OAuth

Client Id dan Client Secret

Untuk memanfaatkan resource dari aplikasi provider, aplikasi client harus memiliki client id dan client secret yang diberikan oleh aplikasi provider. Berikut adalah halaman untuk mendapatkan client id dan client secret untuk beberapa layanan OAuth Provider:

Facebook: https://www.facebook.com/developers/createapp.php

Google: http://code.google.com/apis/console

Github: http://github.com/account/applications/new

Redirect Uri

Ini adalah sebuah halaman yang dipersiapkan khusus oleh aplikasi client untuk memproses callback yang diberikan aplikasi provider. Pada halaman ini aplikasi client akan mengolah informasi yang diberikan oleh aplikasi provider berupa code unik yang harus digunakan untuk proses selanjutnya.

Code

Code adalah sebuah string unik yang diberikan aplikasi provider kepada aplikasi client pada halaman callback yang sebelumnya sudah didefenisikan pada parameter redirect uri. Code dibutuhkan untuk kemudian ditukarkan kembali ke aplikasi provider untuk mendapatkan access token.

Access Token

Access token adalah sebuah string penanda izin otorisasi yang dibutuhkan aplikasi cilent untuk memanfaatkan sumberdaya seorang user yang ada di aplikasi provider. Jika client sudah mendapatkan acces token dari provider maka pertukaran data sudah bisa dilakukan misalnya untuk mendapatkan nama user, foto, email, memposting artikel ke aplikasi provider dll.

Scope

Scope adalah opsi tambahan untuk mendapatkan informasi spsifik pada user yang umumnya secara default tidak langsung diberikan oleh aplikasi provider.

User Authentication

Pertama-tama user harus login dan melakukan proses otentifikasi di aplikasi provider. Aplikasi client harus me-redirect usernya ke sebuah halaman otentifikasi yang sudah ditentukan oleh aplikasi provider. Pada saat melakukan proses ini, aplikasi client harus menyertakan parameter client_id dan redirect_uri pada alamat url halaman otentifikasi. Contohnya seperti berikut:

https://www.appprovider.com/login_page?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL

Contoh halaman otentifikasi Facebook:

https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL

Contoh halaman otentifikasi Google:

https://accounts.google.com/o/OAuth 2/auth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL

Contoh halaman otentifikasi Github:

https://github.com/login/oauth/authorize?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL

Jika proses login berhasil, user kemudian akan dibawa kehalaman dialog dimana dia akan diberikan pilihan apakah akan mengizinkan resource-nya diakses oleh aplikasi client atau tidak. Jika user memberikan uzin, maka selanjutnya user akan diredirect ke halaman callback aplikasi client yang nilainya sudah diisikan pada parameter redirect_uri.

Proses konfirmasi ini hanya dilakukan sekali saja. Jika user sudah pernah memberikan izin maka akan langsung diarahkan ke halaman callback.

Jika aplikasi client membutuhkan informasi tambahan yang tidak langsung disediakan oleh aplikasi client, maka pada tahap ini parameter scope bisa ditambahakan. Setiap penyedia layanan OAuth provider memiliki daftarnya sendiri-sendiri. Sebagai contoh berikut contoh penggunaan scope pada halaman otentifikasi Facebook:

https://www.facebook.com/dialog/oauth?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_URL&scope=email,read_stream

Daftar pilihan scope Facebook bisa dilihat di halaman https://developers.facebook.com/docs/authentication/permissions

Contoh penggunaan scope pada Google

https://accounts.google.com/o/OAuth 2/auth?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_URL&scope=https://mail.google.com/mail/feed/atom/&response_type=code

Mendapatkan Access Token

Setelah user diredirect ke halaman callback aplikasi client, maka proses selanjutnya adalah memanfaatkan argument code yang disertakan pada alamat url. Contoh alamat url halaman callback yang di-redirect dari aplikasi provider:

http://www.appclient.com/callback_page?code=A_CODE_GENERATED_BY_PROVIDER

Proses selanjutnya adalah mengirimkan kembali nilai variabel code ke aplikasi provider melalui hattp request untuk ditukarkan dengan akses token. Jika berhasil API aplikasi provider akan memberikan response string yang berisi access token dan berapa lama masa berlakunya.

String access token yang sudah didapatkan harus disimpan untuk keperluan penggunaan resource user pada aplikasi provider.

Menggunakan Resource User

Sampai pada tahap ini aplikasi client sudah siap untuk memanfaatkan resource yang tersedia pada aplikasi provider. Sebagai contoh jika kita ingin mendapatkan nama dan informasi tentang user maka aplikasi client harus melakukan request ke apliaksi provider dengan alamat yang sudah ditentukan olehnya dengan menyertakan access token yang sudah didapatkan sebelumnya. Sebagai contoh jika ingin mendapatkan basic info dari Facebook alamat API yang harus diakses dengan method GET adalah:

https://graph.facebook.com/me?access_token=ACCESS_TOKEN

Contoh mendapatkan user info pada Gituhub:

https://github.com/api/v2/json/user/show?access_token=ACCESS_TOKEN

Contoh memposting artikel di Blogger:

POST http://www.blogger.com/feeds/blogID/posts/default?oauth_token=ACCESS_TOKEN
dengan isi body post:

<entry xmlns='http://www.w3.org/2005/Atom'>
  <title type='text'>Marriage!</title>
  <content type='xhtml'>
    <div xmlns="http://www.w3.org/1999/xhtml">
      <p>Mr. Darcy has <em>proposed marriage</em> to me!</p>
      <p>He is the last man on earth I would ever desire to marry.</p>
      <p>Whatever shall I do?</p>
    </div>
  </content>
  <category scheme="http://www.blogger.com/atom/ns#" term="marriage" />
  <category scheme="http://www.blogger.com/atom/ns#" term="Mr. Darcy" />
</entry>

Membuat Aplikasi Client

Berikut kita akan membuat contoh aplikasi client OAuth dengan menggunakan Facebook sebagai OAuth provider. Pastikan Anda telah memiliki client id dan client secret yang diberikan oleh Facebook. Silahkan mendaftar di halaman https://www.facebook.com/developers/createapp.phpjika belum.

Pada contoh yang akan digunakan menggunakan framework Panada, namun bisa juga diimplementasikan pada framework lain atau bahkan PHP scratch. Sebagai catatan contoh yang digunakan di bawah ini ditulis sesederhana mungkin sehingga mengabaikan pakem MVC dengan tujuan untuk mempermudah penjelasan.

Pertama-tama kita membutuhkan dua buah file class PHP yaitu oauth2_client.php dan rest.php.

Khusus bagi Anda yang menggunakan Panada, class rest sudah tersedia pada core library sehingga tidak perlu lagi didownload.

Buat sebuah controller baru bernama auth bagi Anda yang menggunakan framework atau file baru bernama auth.php bagi yang memilih scratch.

Letakan oauth2_client.php dan rest.php pada folder library atau vendor atau apapun namanya di dalam framework yang Anda gunakan. Sedakan pada PHP scratch letakan satu level dengan file auth.php agar lebih mudah untuk melakukan include. Jika folder document root localhost Anda berada di:

/var/www/public_html/

Maka tambahkan satu folder beru bernama client, sehingga strukturnya menjadi:

/var/www/public_html/client/

Berikut adalah isi controller auth pada Panada:

<?php

class Controller_auth extends Panada {

    public function __construct(){

        parent::__construct();

        $this->rest = new Library_rest();
        $this->oauth2_client = new Library_oauth2_client();

        $this->oauth2_client->client_id = 'MY_CLIENT_ID';
        $this->oauth2_client->client_secret = 'MY_CLIENT_SECRET';
        $this->oauth2_client->redirect_uri = 'http://localhost/client/auth/callback';
    }

    public function index(){

        $provider_auth_uri = 'https://www.facebook.com/dialog/oauth';
        $more_args = array( 'scope' => 'email' );

        $this->oauth2_client->user_authentication( $provider_auth_uri, $more_args );
    }

    public function callback(){

        $code = $_GET['code'];
        $provider_token_uri = 'https://graph.facebook.com/oauth/access_token';

        $response = $this->oauth2_client->get_access_token( $provider_token_uri, $code );

        parse_str($response);

        $provider_uri = 'https://graph.facebook.com/me';

        $response = $this->oauth2_client->access_user_resources( $provider_uri, $access_token );

        $data = json_decode( $response );

        print_r($data);
    }
}

Berikut isi file auth.php pada PHP scretch:

<?php

require_once 'rest.php';
require_once 'oauth2_client.php';

$rest = new Library_rest();
$oauth2_client = new Library_oauth2_client();

$oauth2_client->client_id = 'MY_CLIENT_ID';
$oauth2_client->client_secret = 'MY_CLIENT_SECRET';
$oauth2_client->redirect_uri = 'http://localhost/client/auth.php?callback';

if( isset($_GET['login']) ) {

    $provider_auth_uri = 'https://www.facebook.com/dialog/oauth';
    $more_args = array( 'scope' => 'email' );

    $oauth2_client->user_authentication( $provider_auth_uri, $more_args );
}

if( isset($_GET['callback']) ) {

    $code = $_GET['code'];
    $provider_token_uri = 'https://graph.facebook.com/oauth/access_token';

    $response = $oauth2_client->get_access_token( $provider_token_uri, $code );

    parse_str($response);

    $provider_uri = 'https://graph.facebook.com/me';

    $response = $oauth2_client->access_user_resources( $provider_uri, $access_token );

    $data = json_decode( $response );

    print_r($data);
}

Sekarang akses alamat http://localhost/client/auth jika Anda menggunakan framework atau alamat http://localhost/client/auth.php?login jika PHP scratch.

Jika tidak ada masalah akan muncul dump array yang berisi data personal Anda yang ada di Facebook. Data inilah yang kemudian akan kita manfaatkan untuk meng-otentifikasi user pada aplikasi kita.

Data ini bisa kita gunakan untuk:

  1. Melakukan pengecekan ke dalam database apakah data user ini sudah pernah tersimpan sebelumnya. Field email bisa kita gunakan sebagai identifer unik. Jika tidak ada maka simpan datanya ke dalam database.
  2. Jika data sudah pernah tersimpan kita bisa langsung menyimpan nilai-nilainya ke dalam session dan memastikan user sudah terotentifikasi di aplikasi kita.

Berikut contoh kode implementasi data yang sudah didapat dan di-assign menjadi session pada framework Panada:

<?php

class Controller_auth extends Panada {

    public function __construct(){

        parent::__construct();

        $this->rest = new Library_rest();
        $this->oauth2_client = new Library_oauth2_client();
        $this->session = new Library_session(); 

        $this->oauth2_client->client_id = '126220237453638';
        $this->oauth2_client->client_secret = 'd363579077a9ef22c5bbd871736212f1';
        $this->oauth2_client->redirect_uri = 'http://panadaframework.com/auth/callback';
    }

    public function index(){

        $provider_auth_uri = 'https://www.facebook.com/dialog/oauth';

        $more_args = array( 'scope' => 'email' );

        $this->oauth2_client->user_authentication( $provider_auth_uri, $more_args );
    }

    public function callback(){

        $code = $_GET['code'];
        $provider_token_uri = 'https://graph.facebook.com/oauth/access_token';

        $response = $this->oauth2_client->get_access_token( $provider_token_uri, $code );

        parse_str($response);

        $provider_uri = 'https://graph.facebook.com/me';

        $response = $this->oauth2_client->access_user_resources( $provider_uri, $access_token );

        $data = json_decode( $response );

        $this->session->set(
            array(
                'is_login' => 1,
                'name' => $data->name,
                'id' => $data->id,
            )
        );

        $this->redirect('auth/restricted_page');
    }

    public function restricted_page(){

        if( ! $this->session->get('is_login') )
            $this->redirect('auth');

        echo 'Selamat datang <b>' . $this->session->get('name') . '</b> | <a href="'.$this->location('auth/signout').'">Sign Out</a>';
    }

    public function signout(){

        $this->session->session_clear_all();

        echo 'Anda kini telah logout. Klik <a href="'.$this->location('auth').'">Sign In</a> untuk kembali login.';
    }
}

Implementasi juga bisa diterapkan aplikasi non framework. Berikut isi file auth.php pada PHP scretch:

<?php
session_start();

require_once 'rest.php';
require_once 'oauth2_client.php';

$rest = new Library_rest();
$oauth2_client = new Library_oauth2_client();

$oauth2_client->client_id = '126220237453638';
$oauth2_client->client_secret = 'd363579077a9ef22c5bbd871736212f1';
$oauth2_client->redirect_uri = 'http://panadaframework.com/auth.php?callback';

if( isset($_GET['login']) ) {

    $provider_auth_uri = 'https://www.facebook.com/dialog/oauth';
    $more_args = array( 'scope' => 'email' );

    $oauth2_client->user_authentication( $provider_auth_uri, $more_args );
}

if( isset($_GET['callback']) ) {

    $code = $_GET['code'];
    $provider_token_uri = 'https://graph.facebook.com/oauth/access_token';

    $response = $oauth2_client->get_access_token( $provider_token_uri, $code );

    parse_str($response);

    $provider_uri = 'https://graph.facebook.com/me';

    $response = $oauth2_client->access_user_resources( $provider_uri, $access_token );

    $data = json_decode( $response );

    $_SESSION['is_login'] = 1;
    $_SESSION['name'] = $data->name;
    $_SESSION['id'] = $data->id;

    header('Location:auth.php?restricted_page');
    exit;
}

if( isset($_GET['restricted_page']) ) {

    if( ! $_SESSION['is_login'] )
        header('Location:auth.php?login');

    echo 'Selamat datang <b>' . $_SESSION['name'] . '</b> | <a href="auth.php?signout">Sign Out</a>';
}

if( isset($_GET['signout']) ) {

    session_unset();
    session_destroy();

    echo 'Anda kini telah logout. Klik <a href="auth.php?login">Sign In</a> untuk kembali login.';
}

Membuat Aplikasi Provider

Sampai pada tahap ini kita sudah berhasil membuat aplikasi OAuth client dan memanfaatkan datanya untuk otentifikasi pada aplikasi kita. Untuk mengembangakn sistem SSO pada layanan yang kita kelola sendiri, kita membutuhkan sebuah aplikasi provider. Aplikasi ini nantinya juga akan kita manfaatkan sebagai pusat pengelolaan data dari seluruh member yang terdaftar pada seluruh layanan. Kalau kita perhatikan beberapa penyedia layanan internet yang telah mengimplementasikan SSO mereka juga melakukan pengelolaan user secara terpusat. Sebagai contoh Google akan mengarahkan user yang akan login di layanan mereka ke alamat https://www.google.com/accounts/Login?continue=ALAMAT_LAYANAN_GOOGLE dan Yahoo mengarahkan ke alamat https://login.yahoo.com/config/login_verify2?.intl=us&.src=KODE_LAYANAN&.done=ALAMAT_LAYANAN_YAHOO.

Perlu diperhatikan, OAuth 2.0 mensyaratkan penggunaan SSL (https) protokol untuk penggunaan production OAuth provider. Untuk kemudahan, semua contoh aplikasi provider dalam tulisan ini hanya menggunakan http.

Pertama-tama siapkan sebuah folder baru di document root dengan nama provider sehingga struktrunya seperti berikut:

/var/www/public_html/provider/

Kita akan membuat satu file baru yang akan diletakan di dalam folder ini. Beri nama file tersebut user.php untuk non framework dan buat controller baru bernama user untuk yang menggunakan framework.

Untuk mengelola user kita membutuhkan sebuah database penyimpanan, misalnya kita beri nama SSO. Berikut ini struktur tabel-tabel dan data contoh yang diperlukan:

CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(32) NOT NULL,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
);

INSERT INTO `users` (`username`, `password`, `name`) VALUES
('user', 'ee11cbb19052e40b07aac0ca060c23ee', 'Budi');

CREATE TABLE `access_privileges` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_id` INT UNSIGNED NOT NULL,
`client_id` varchar(32) NOT NULL,
`code` VARCHAR(32) NOT NULL,
`access_token` VARCHAR(32) NOT NULL,
`redirect_uri` TEXT NOT NULL,
`expires` BIGINT UNSIGNED NOT NULL
);

CREATE TABLE `apps_clients` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`client_id` VARCHAR(32) NOT NULL,
`client_secret` VARCHAR(32) NOT NULL,
`logout_url` TEXT NOT NULL
);

INSERT INTO `apps_clients` (
`id`, `client_id`, `client_secret`, `logout_url`)
VALUES (NULL, 'c4ca4238a0b923820dcc509a6f75849b',
'4fc9b72a83a99a594d40b3971874a9be',
'http://localhost/client/auth.php?self_logout'
);

Setting konfigurasi framework yang Anda gunakan sesuai dengan environment development agar bisa terkoneksi dengan database server. Buat sebuah contorller baru bernama user atau file baru bernama user.php jika menggunakan PHP scretch. Berikut contoh isi controller-nya:

<?php

class Controller_user extends Panada {

    public function __construct(){

        parent::__construct();

        $this->db = new Library_db();
        $this->rest = new Library_rest();
        $this->request = new Library_request();
        $this->session = new Library_session(); 

    }

    public function index(){

    }

    public function signin(){

        if( ! $this->session->get('is_provider_login') ) {

            $error = null;
            $client_id = $_GET['client_id'];
            $redirect_uri = urldecode($_GET['redirect_uri']);
            $parsed = parse_url($redirect_uri);

            if( isset($parsed['query']) )
                parse_str($parsed['query'], $query_args);

            if( isset($_POST['submit']) ){

                if( $user = $this->db->get_row('users', array('username' => $_POST['username'], 'password' => md5($_POST['password'])) ) ) {

                    $query_args['code'] = rand();
                    $access_token = rand();
                    $expires = strtotime('next hour');
                    $parsed['host'] = rtrim($parsed['host'], '/').'/';
                    $redirect_to = $parsed['scheme'].'://'.$parsed['host'];

                    if( isset($parsed['path']) )
                        $redirect_to .= $parsed['path'];

                    $redirect_to .= '?'.http_build_query( $query_args );

                    if( isset($parsed['fragment']) )
                        $redirect_to .= '#'.$parsed['fragment'];

                    $this->db->delete('access_privileges',
                                      array(
                                        'client_id' => $client_id,
                                        'user_id' => $user->id
                                        )
                                    );

                    $this->db->insert('access_privileges',
                                      array(
                                        'client_id' => $client_id,
                                        'user_id' => $user->id,
                                        'code' => $query_args['code'],
                                        'access_token' => $access_token,
                                        'redirect_uri' => $redirect_uri,
                                        'expires' => $expires
                                    )
                                );

                    $this->session->set( array('is_provider_login' => $user->id, 'name' => $user->name) );

                    $this->redirect( $redirect_to );
                }

                $error = '<p>Username atau password salah.</a>';
            }

            echo $error;
            echo '<form action="" method="post">';
            echo 'Username: <input type="text" name="username" /><br />';
            echo 'Password: <input type="password" name="password" /><br />';
            echo '<input type="submit" name="submit" value="Sign In" /><br />';
            echo '</form>';
        }
        else {

            echo 'Hallo <b>'.$this->session->get('name').'</b> Saat ini Anda sudah login di OAuth Provider | <a href="signout">Sign Out</a>';
        }
    }

    public function signout(){

        $this->session->session_clear_all();

        echo 'Anda kini telah logout dari OAuth Provider. Silahkan login menggunakan OAuth Client Anda.';
    }

    public function access_token(){

        $code = $this->request->get('code');
        $client_id = $this->request->get('client_id');
        $client_secret = $this->request->get('client_secret');
        $redirect_uri = $this->request->get('redirect_uri');

        $data = (array) $this->db->row("SELECT
                                    access_privileges.access_token, access_privileges.expires
                                FROM
                                    access_privileges, apps_clients
                                WHERE
                                    apps_clients.client_id = access_privileges.client_id AND
                                    apps_clients.client_id = '$client_id' AND
                                    apps_clients.client_secreet = '$client_secret' AND
                                    access_privileges.redirect_uri = '$redirect_uri' AND
                                    access_privileges.code = '$code'

                            ");

        if( ! $data )
            $data['error'] = 'Argument query yang Anda berikan tidak cocok.';

        echo urldecode(http_build_query($data));
    }

    public function get_data(){

        $access_token = $this->request->get('access_token');

        $data = $this->db->row("
                            SELECT
                                users.id, users.username, users.name
                            FROM
                                access_privileges, users
                            WHERE
                                users.id = access_privileges.user_id AND
                                access_privileges.access_token = '$access_token'
                        ");

        if( ! $data )
            $data['error'] = 'Argument query yang Anda berikan tidak cocok.';

        echo $this->rest->wrap_response_output($data, 'javascript');

    }
}

Dan berikut isi file user.php jika menggunakan PHP scretch:

<?php
session_start();

$link = mysql_connect('localhost', 'root', '');
$db_selected = mysql_select_db('komps', $link);

if( isset($_GET['signin']) ) {

    if( ! isset($_SESSION['is_provider_login']) ){

        $error = null;
        $client_id = $_GET['client_id'];
        $redirect_uri = urldecode($_GET['redirect_uri']);
        $parsed = parse_url($redirect_uri);

        if( isset($parsed['query']) )
            parse_str($parsed['query'], $query_args);

        if( isset($_POST['submit']) ){

            if( $user = mysql_fetch_object( mysql_query("SELECT * FROM users WHERE username = '".$_POST['username']."' AND password = '".md5($_POST['password'])."'")) ) {

                $query_args['code'] = rand();
                $access_token = rand();
                $expires = strtotime('next hour');
                $parsed['host'] = rtrim($parsed['host'], '/').'/';
                $redirect_to = $parsed['scheme'].'://'.$parsed['host'];

                if( isset($parsed['path']) )
                    $redirect_to .= $parsed['path'];

                $redirect_to .= '?'.http_build_query( $query_args );

                if( isset($parsed['fragment']) )
                    $redirect_to .= '#'.$parsed['fragment'];

                mysql_query("DELETE FROM access_privileges WHERE client_id = '$client_id' AND user_id = $user->id");
                mysql_query("INSERT INTO access_privileges (client_id, user_id, code, access_token, redirect_uri, expires) VALUES ('$client_id', '$user->id', '".$query_args['code']."', '$access_token', '$redirect_uri', '$expires')");

                $_SESSION['is_provider_login'] = $user->id;
                $_SESSION['name'] = $user->name;

                header('Location:'.$redirect_to);
            }

            $error = '<p>Username atau password salah.</a>';
        }

        echo $error;
        echo '<form action="" method="post">';
        echo 'Username: <input type="text" name="username" /><br />';
        echo 'Password: <input type="password" name="password" /><br />';
        echo '<input type="submit" name="submit" value="Sign In" /><br />';
        echo '</form>';
    }
    else {

        echo 'Hallo <b>'.$_SESSION['name'].'</b> Saat ini Anda sudah login di OAuth Provider | <a href="?signout">Sign Out</a>';
    }
}

if( isset($_GET['signout']) ) {

    session_destroy();

    echo 'Anda kini telah logout dari OAuth Provider. Silahkan login menggunakan OAuth Client Anda.';
}

if( isset($_GET['access_token']) && ! isset($_GET['get_data']) ){

    $code = $_GET['code'];
    $client_id = $_GET['client_id'];
    $client_secret = $_GET['client_secret'];
    $redirect_uri = $_GET['redirect_uri'];

    $data = mysql_fetch_array(
                            mysql_query("
                                SELECT
                                    access_privileges.access_token, access_privileges.expires
                                FROM
                                    access_privileges, apps_clients
                                WHERE
                                    apps_clients.client_id = access_privileges.client_id AND
                                    apps_clients.client_id = '$client_id' AND
                                    apps_clients.client_secreet = '$client_secret' AND
                                    access_privileges.redirect_uri = '$redirect_uri' AND
                                    access_privileges.code = '$code'

                            "), MYSQL_ASSOC);

    if( ! $data )
        $data['error'] = 'Argument query yang Anda berikan tidak cocok.';

    echo urldecode(http_build_query($data));
}

if( isset($_GET['get_data']) ){

    $access_token = $_GET['access_token'];

    $data = mysql_fetch_object(
                        mysql_query("
                            SELECT
                                users.id, users.username, users.name
                            FROM
                                access_privileges, users
                            WHERE
                                users.id = access_privileges.user_id AND
                                access_privileges.access_token = '$access_token'
                        ")
                    );

    if( ! $data )
        $data['error'] = 'Argument query yang Anda berikan tidak cocok.';

    echo json_encode($data);
}

Sekarang kita coba dengan terlebih dahulu memodifikasi aplikasi client yang sebelumnya sudah kita buat. Sesuaikan alamat url provider seperti berikut ini:

<?php
session_start();

require_once 'rest.php';
require_once 'oauth2_client.php';

$rest = new Library_rest();
$oauth2_client = new Library_oauth2_client();

$oauth2_client->client_id = 'c4ca4238a0b923820dcc509a6f75849b';
$oauth2_client->client_secret = '4fc9b72a83a99a594d40b3971874a9be';
$oauth2_client->redirect_uri = 'http://localhost/client/auth.php?callback';

if( isset($_GET['login']) ) {

    $provider_auth_uri = 'http://localhost/provider/user.php';
    $more_args = array( 'scope' => 'email', 'signin' => 'true' );

    $oauth2_client->user_authentication( $provider_auth_uri, $more_args );
}

if( isset($_GET['callback']) ) {

    $code = $_GET['code'];
    $provider_token_uri = 'http://localhost/provider/user.php';

    $response = $oauth2_client->get_access_token( $provider_token_uri, $code, 'GET', array('access_token' => 'true') );

    parse_str($response);

    $provider_uri = 'http://localhost/provider/user.php';

    $response = $oauth2_client->access_user_resources( $provider_uri, $access_token, 'GET', array('get_data' => 'true') );

    $data = json_decode( $response );

    $_SESSION['is_login'] = 1;
    $_SESSION['name'] = $data->name;
    $_SESSION['id'] = $data->id;

    header('Location:_auth.php?restricted_page');
    exit;
}

if( isset($_GET['restricted_page']) ) {

    if( ! $_SESSION['is_login'] )
        header('Location:auth.php?login');

    echo 'Selamat datang <b>' . $_SESSION['name'] . '</b> | <a href="auth.php?signout">Sign Out</a>';
}

if( isset($_GET['signout']) ) {

    session_unset();
    session_destroy();

    echo 'Anda kini telah logout. Klik <a href="auth.php?login">Sign In</a> untuk kembali login.';
}

if ( isset($_GET['self_logout']) ){

    session_unset();
    session_destroy();
}

Sekarang kembali akses alamat http://localhost/client/auth.php?login dari browser Anda. Jika berhasil di browser akan menampilkan pesan “selamat datang budi”.

Crossdomain Authentication

Untuk pengujian lebih lanjut, kita harus pastikan bahwa mekanisme SSO yang sudah kita buat bisa berjalan pada domain yang berbeda-beda (crossdomain authentication). Untuk itu silahkan buat virtual host baru di komputer Anda dengan nama domain selain localhost, misalnya myhost. Setelah berhasil pastikan Anda menambahakan nilai:

127.0.0.1 myhost

di dalam folder:

/etc/hosts

Konfigurasi ini bertujuan ketika diakses dari browser dengan alamat http://myhost/ akan mengarahkan ke komputer yang sedang kita gunakan.

Setaleh dipastikan berhasil, letakkan aplikasi provider yang sudah kita buat ke folder virtual host myhost sehingga alamat url aplikasi provider-nya menjadi

http://myhost/provider/

Sesuaikan kembali parameter yang ada pada code aplikasi client dan silahkan coba kembali.

Single Sign On/Out

Kini kedua aplikasi sudah berjalan sesuai harapan. Kita bisa melakukan otentifikasi user dari satu aplikasi ke aplikasi lainnya tanpa perlu lagi mengisikan username atau password. Namun sampai tahap ini prosesnya masih berjalan manual. User harus mengklik link terlebih dahulu untuk bisa terotentifikasi.

Langkah selanjutnya adalah kita akan membuat user benar-benar merasakan Single Sign On. Sebagi contoh user login di aplikasi dengan domain myshost, kemudian dia membuka halaman baru dengan domain localhost, maka kita ingin dia juga sudah terotentifikasi. Hal yang sama juga berlaku ketika user logout. Logout di satu aplikasi maka ter-logout juga di aplikasi lainnya.

Untuk melakukan hal ini kita akan menggunakan bantuan javascript sebagai login redirector, dan tag html img sebagai pen-triger logout.

Javascript Login Redirector

Buat sebuah blok baru di dalam file user.php atau controller controller user. Tugas blok ini adalah mendeteksi apakah seorang user sudah login pada aplikasi provider atau belum. Jika sudah login maka bagian ini akan mencetak output javascript yang me-redirect ke halaman login provider. Berikut contoh code-nya:

<?php
session_start();

header("Content-type: text/javascript");

if( isset($_SESSION['is_provider_login']) ){
    echo 'top.location.href=" http://myhost/provider/user.php?client_id=c4ca4238a0b923820dcc509a6f75849b&redirect_uri=http://localhost/client/auth.php?callback&signin=true";';
}

File ini akan dianggap file javascript oleh browser, sehingga untuk meload-nya kita gunakan tag <script> seperti berikut:

<script type="text/javascript" src="http://myhost/provider/user.php?redirector"></script>

Letakkan script ini disetiap halaman aplikasi clent yang ingin login secara otomatis. Gunakan script ini hanya dalam kondisi user belum login di aplikasi client.

Img Logout Triger

Terakhir untuk ‘memakasa’ aplikasi client melakukan logout tambahkan code berikut di bagian logout aplikasi provider:

if( isset($_GET['signout']) ) {

    session_destroy();

    $result = mysql_query( "SELECT logout_url FROM apps_clients" );

    while ($row = mysql_fetch_object($result)) {
        echo '<img src="'.$row->logout_url.'" width="0" height="0" alt="" />';
    }
}

Sebagaimana kita lihat untuk melakukan logout client aplikasi provider membutuhkan alamat url ‘self logout’ dari client. Nilai ini harus diisikan ketika akan menambahkan aplikasi client baru.

Untuk memusatkan proses logout, semua client harus melakukan logout di aplikasi provider dengan cara memberikan link logout ke halaman logout provider.

<a href="http://myhost/provider/user.php?signout&redirect_to=http://localhost/client/auth.php?signout">Logout</a>

 

Elearning


Di Inggris banyak sekolah yang membuat design dan program teknologi sebagai bagian dari pengembangan kurikulum untuk melatih problem solving (pemecahan masalah) dan mengembangkan kreatifitas anak-anak. Anak-anak lebih suka bergerak (mobile), laptop, internet, video dan sosial media untuk mengklarifikasi keraguan mereka dan untuk melakukan tugas-tugas mereka.

Pendidikan online di bingkai untuk mengatasi kesenjangan ketrampilan dan mendapatkan perhatian dari pelajar di seluruh dunia.

Adaptive learning, virtual classroom, Massive Open Online Course(MOOC), synchronous learning, asynchronous learning, blended learning, flipped classroom, self-directed learning,  learning management system, cloud based learning, mobile learning, course management system, e-learning and Gamification adalah konsep teknologi yang guru butuhkan untuk mentraining siswa pada generasi ini

 

Ibadah


AYAT 56

وَمَا خَلَقْتُ الْجِنَّ وَالْإِنْسَ إِلَّا لِيَعْبُدُونِ

“Dan tidaklah Aku ciptakan Jin dan Manusia kecuali untuk beribadah kepadaku” (Q.S adz-Dzaariyaat ayat 56)

Semua dimensi kehidupan manusia seharusnya adalah ibadah

Jika di dalam al-Quran dan hadits terdapat perintah terhadap sesuatu, maka sesuatu itu adalah ibadah. Jika Allah dan RasulNya melarang sesuatu, maka meninggalkan sesuatu itu adalah ibadah.

Perintah Allah itu adalah menjadi sebab manusia berbuat atau beramal, dalam berbuat atau beramal yang harus diperkuat adalah sebabnya.

Ada sekian hal yang Allah lepas pada manusia untuk menjadi perintah sebab, semakin kuat sebabnya semakin dekat rahmat Allah, itu sebabnya kenapa seberat apapun urusan Rasullah itu yang diperkuat pertama kali oleh Rasullah adalah sebabnya.

perintah Allah baik yang bersifat Rububiyyah (rezeki, kekuasaan) biasanya ayatnya diawali kata yaa ayuhannas, maupun yang bersifat uluhiyah (ibadah) biasanya ayatnya yaa ayuhaladzina amanu.

ketika di dunia Ibadah adalah penyempurna perintah NYA untuk mendapatkan rahmat NYA. Jika kita sudah mendapatkan rahmat Allah maka ibadah itu merupakan karunia yang diberikan ke umat muslim.

Ketika di syurga Ibadah adalah karunia yang diberikan kepada umat Muslim untuk mendapatkan rahmat NYA, karena non muslim pasti tidak di syurga.

Jadi jika kita sudah disurga maka kita akan sangat bersyukur karena kita sudah diberikan karunia ibadah tersebut.

Ibadah harus dengan ilmu

54 % Muslim selalu shalat dan tidak pernah meninggalkan shalat

23 % Pernah meninggalkan shalat kadang-kadang

9,6 % yang selalu mengaji

15 % sering mengaji

karena ilmu itu adalah pintu orang menjadi benar, maka setan lebih fokus ke orang yang mengaji.

orang yang tobatnya diujung seringkali mengabaikan perkara-perkara sederhana yang mendasari perkara pokok.

  1. belajar najis diabaikan karena fokus belajar shalat.
  2. belajar wudhu diabaikan, fokus ke khusyu shalat

 

Hujan sebagai analogi rizki


Hujan

مَا يَفْتَحِ اللَّهُ لِلنَّاسِ مِنْ رَحْمَةٍ فَلَا مُمْسِكَ لَهَا وَمَا يُمْسِكْ فَلَا مُرْسِلَ لَهُ مِنْ بَعْدِهِ وَهُوَ الْعَزِيزُ الْحَكِيمُ

Apa saja yang Allah anugerahkan kepada manusia berupa rahmat, maka tidak ada seorang pun yang dapat menahannya; dan apa saja yang ditahan oleh Allah maka tidak seorangpun yang sanggup melepaskannya sesudah itu. dan Dialah yang Maha Perkasa lagi Maha Bijaksana.” (QS. Fathir: 2).

يَا أَيُّهَا النَّاسُ اذْكُرُوا نِعْمَةَ اللَّهِ عَلَيْكُمْ هَلْ مِنْ خَالِقٍ غَيْرُ اللَّهِ يَرْزُقُكُمْ مِنَ السَّمَاءِ وَالْأَرْضِ

Hai manusia, ingatlah akan nikmat Allah kepadamu. Adakah Pencipta selain Allah yang dapat memberikan rezki kepada kamu dari langit dan bumi?” (QS. Fathir: 3)

قُلْ مَنْ يَرْزُقُكُمْ مِنَ السَّمَاوَاتِ وَالْأَرْضِ قُلِ اللَّهُ
Katakanlah: “Siapakah yang memberi rezeki kepadamu dari langit dan dari bumi?” Katakanlah: “Allah.” (QS. Saba’: 24)

Bahwa rezeki bisa dari langit dan dari bumi,

rezeki dari langit :

  • Hujan
  • Besi, emas, dan logam lainnya berdasarkan penelitian besi berasal dari luar angkasa, ketika meteor menabrak bumi jutaan tahun yang lalu
  • Frekuensi, pengunaan frekuensi saat ini juga merupakan rezeki
  • Atau mungkin masih banyak rezeki lain diatas sana, diplanet-planet diluar angkasa

rezeki dari bumi :

  • Tumbuhan
  • Minyak bumi
  • Hasil tambang
  • Atau mungkin masih banyak rezeki lain dibawah sana, karena masih banyak yang belum di eksplore dibawah bumi

Ibadah manusia sesungguhnya adalah untuk memancing rahmat Allah, Ibadah adalah penyempurna perintah Allah untuk mendapatkan rahmat, perintah Allah baik yang bersifat Rububiyyah (rezeki, kekuasaan) maupun yang bersifat uluhiyah (ibadah).

Continue reading

Ramadhan


Doa rasulullah kepada keponakannya Ibnu Abbas :
اللهم فقهه فى الدين و علمه التاءويل
Ya Allah, fahamkanlah ia (ibnu abbas) dalam semua permasalahan agama, dan berikanlah ia ilmu untk bisa menta’wilkan (tafsirkan al qur’an)

Ketika berdoa bisa menggunakan isim domir nahnu ma’al ghoir :

اللهم فقهنا فى الدين وعلمنا التاءويل
Allahumma faqqihna fiddin wa ‘allimnat ta’wil

Ya Allah, fahamkanlah kami dalam semua permasalahan agama, dan berikanlah kami ilmu bisa menta’wilkan (menafsirkan al qur’an)⁠⁠⁠⁠

Ayo siap2 meraih malam penetapan Allah, malam penuh berkah, diawali dari maghrib sampai subuh, detik demi detik sama waktunya semua diberkahi Allah,
Carilah maka akan dapat lailatul qadar
Ayo :
– i’tikaf
– baca al-qur’an
– ngaji tentang kajian islam
– banyakin doa
Allahumma innaka afuwwun kariim tuhibbul afwa fa’fu ‘anni
اللهم انك عفو كريم تحب العفو فاعف عني
Allahumma inna nas-aluka ridhoka wal jannah wa na’udzubika min sakhotika wan naar
اللهم انا نسالك رضاك والجنة ونعوذ بك من سخطك و النار

Plan(review) Vs. Actual Plan


Dalam analisis akuntansi dan keuangan, perbedaan antara rencana dan aktual disebut varians.
varian dapat memiliki nilai positif (baik) atau negatif (buruk).

Positif Varian

  • Jika selisihnya sebagai angka positif.
  • Jika Anda menjual lebih dari yang direncanakan, itu positif. Jika keuntungan lebih tinggi dari yang direncanakan, itu positif juga. Jadi untuk penjualan dan keuntungan, varians adalah hasil aktual dikurangi nilai yang direncanakan.
  • Untuk biaya dan pengeluaran, pengeluaran yang kurang dari yang direncanakan positif, jadi varians positif berarti jumlah sebenarnya kurang dari jumlah yang direncanakan. Untuk menghitungnya, kurangi biaya yang direncanakan dengan hasil aktual dari biaya

Negatif Varian

  • Jika selisihnya sebagai angka negatif.
  • Bila penjualan atau keuntungan kurang dari yang direncanakan, itu negatif. Anda menghitung varians pada penjualan dan keuntungan dengan mengurangi hasil aktual dengan nilai rencana.
  • Bila biaya atau pengeluaran lebih dari yang direncanakan, itu juga negatif. Sekali lagi, Anda mengurangi nilai yang direncanakan dengan hasil aktual  .

Contoh sales varian

sales-variance-analysis

contoh expenses varian

expense-variance-analysis.jpg

Analyzing the Marketing Expense Case

Continue reading

Blended Learning


Blended Learning, bisa juga disebut dengan Hybrid Learning, sesuai dengan namanya merupakan suatu metode pembelajaran yang mengkombinasikan metode pembelajaran tatap muka dengan online learning.

Metode pembelajaran bisa berupa tatap muka sehari – hari, kemudian ada beberapa komponen pembelajaran e – learning yang disisipkan, maupun sebaliknya, kebanyakan pembelajaran e- learning, lalu disisipkan metode tatap muka untuk review atau untuk ujian.

Ada yang perlu diperhatikan oleh peserta saat hendak mengikuti metode pembelajaran ini adalah komitmen waktu untuk mempelajari suatu topik, kemampuan untuk beradaptasi dengan metode pembelajaran yang berbeda dari biasanya,

Metode pembelajaran ini bisa jadi menjadi suatu solusi yang baik untuk memenuhi kebutuhan market, dimana metode pembelajaran tatap muka dirasa sulit karena adanya kendala waktu maupun tempat, adanya pengurangan biaya operasional, peserta dapat menentukan sendiri kecepatan mereka dalam belajar, tidak terikat waktu namun tetap harus memiliki komitmen.

Mari kita lihat dari sisi peserta
Kelebihan untuk “saya sebagai peserta”:

  • Belajar kapan pun saya mau
  • Belajar dengan kecepatan yang saya inginkan
  • Mendapatkan pengalaman belajar dengan metode berbeda
  • Ada waktu untuk memperdalam suatu topik, sebelum membahas dengan trainer

Kekurangannya:

  • Harus memiliki komitmen waktu, karena saat tidak face-to-face tidak ada waktu tersendiri untuk belajar

Kesimpulannya, bisa kita katakan bahwa blended learning memberikan peserta suatu kesempatan untuk mempelajari/mengembangkan suatu keahlian berdasarkan self motivation, manajemen waktu dan konsentrasi (kemampuan untuk tetap fokus)

Sekarang kita lihat dari sisi pemberi training, sisi pemberi training disini dalam hal ini bisa jadi adalah lembaga yang menyediakan training, maupun perusahaan yang men-support blended learning

Kelebihan untuk “saya sebagai penyedia training”:

  • Beban biaya operasional training berkurang, begitu juga dengan biaya instruktur yang harus dibayarkan
  • Untuk perusahaan, karyawannya masih tetap ada di kantor bekerja sekaligus mempelajari suatu keahlian/topik
  • Konten training bisa diadaptasikan sesuai kebutuhan bisnis

Kekurangannya:

  • Saya harus mencari orang yang tepat untuk mendeliver materi agar tujuan dari pembelajaran benar – benar tersampaikan
  • Peserta tetap membutuhkan face-to-face untuk melengkapi pembelajaran
  • Training harus lebih serius, tidak sekedar main – main

Profesor McGinnis (2005) dalam artikelnya yang berjudul ‘Building A Successful Blended Learning Strategy’, menyarankan 6 hal yang perlu diperhatikan manakala orang menyelenggarakan blended learning.

Ke-enam hal tersebut adalah sebagai berikut:

  1. Penyampaian bahan ajar dan penyampaian pesan-pesan yang lain (seperti pengumuman yang berkaitan dengan kebijakan atau peraturan) secara konsisten.
  2. Penyelenggaraan pembelajaran melalui blended learning harus dilaksanakan secara serius karena hal ini akan mendorong siswa cepat menyesuaikan diri dengan sistim pendidikan jarak jauh. Konsekuensinya, siswa lebih cepat mandiri.
  3. Bahan ajar yang diberikan harus selalu mengalami perbaikan (updated), baik dari segi formatnya maupun ketersediaan bahan ajar yang memenuhi kaidah ‘bahan ajar mandiri’ (self-learning materials) seperti yang lazim digunakan pada pendidikan jarak jauh.
  4. Alokasi waktu bisa dimulai dengan formula awal 75:25 dalam artian bahwa 75% waktu digunakan untuk pembelajaran online dan 25% waktu digunakan untuk pembelajaran secara tatap muka (tutorial). Karena alokasi waktu ini belum ada yang baku, maka penyelenggara pendidikan bisa membuat ‘uji coba’ sendiri, sehingga diperoleh alokasi waktu yang ideal.
  5. Alokasi waktu tutorial sebesar 25% untuk tutorial, dapat digunakan khusus bagi mereka yang tertinggal, namun bila tidak memungkinkan (misalnya sebagian besar siswa menghendaki pembelajaran tatap muka), maka waktu yang tersedia sebesar 25% tersebut bisa dipakai untuk menyelesaikan kesulitan-kesulitan siswa dalam memahami isi bahan ajar. Jadi semacam penyelenggaraan ‘remedial class’.
  6. Dalam blended learning diperlukan kepemimpinan yang mempunyai waktu dan perhatian untuk terus berupaya bagaimana meningkatkan kualitas pembelajaran.

 

Selanjutnya secara lebih spesifik Profesor Steve Slemer (2005) dan Soekartawi (2005b) menyarankan enam tahapan dalam merancang dan menyelenggarakan blended learning agar hasilnya optimal. Ke-enam tahapan tersebut adalah sebagai berikut:

  1. Tetapkan macam dan materi bahan ajar, kemudian ubah atau siapkan bahan ajar tersebut menjadi bahan ajar yang memenuhi syarat untuk pendidikan jarak jauh. Karena medium pembelajarannya adalah blended – learning, maka bahan ajar sebaiknya dibedakan atau dirancang untuk tiga macam bahan ajar, yaitu:
    1. Bahan ajar yang dapat dipelajari sendiri oleh siswa,
    2. Bahan ajar yang dapat dipelajari melalui cara berinteraksi melalui cara tatap-muka, dan Bahan ajar yang dapat dipelajari melalui cara berinteraksi melalui cara online/web-based learning.
  2. Tetapkan rancangan dari blended learning yang digunakan. Pada tahap ini diperlukan ahli e-Learning untuk membantu. Intinya adalah bagaimana membuat rancangan pembelajaran yang berisikan komponen pendidikan jarak jauh dan tatap-muka yang baik. Karena itu dalam membuat rancangan pembelajaran ini, perlu diperhatikan hal-hal yang berkaitan antara lain:
    1. Bagaimana bahan ajar tersebut disajikan.
    2.  Bahan ajar mana yang bersifat wajib dipelajari dan mana yang sifatnya anjuran guna memperkaya pengetahuan siswa.
    3. Bagaimana siswa bisa mengakses dua komponen pembelajaran tersebut.
    4. Faktor pendukung apa yang diperlukan. Misalnya software apa yang digunakan, apakah diperlukan kerja kelompok, apakah diperlukan learning resource centers (sumber pembelajaran) di daerah-daerah tertentu.
  3. Tetapkan format dari on-line learning- apakah bahan ajar tersedia dalam format html (sehingga mudah di cut and paste) atau dalam format PDF (tidak bisa di cut and paste). Juga perlu di beritahukan ke siswa dan guru hosting apa yang dipakai, yaitu apakah on-line learning tersebut menggunakan internet link apa ?. apakah Yahoo, Google, MSN atau lainnya.
  4. Lakukan uji terhadap rancangan yang dibuat. Ini maksudnya apakah rancangan pembelajaran tersebut bisa dilaksanakan dengan mudah atau sebaliknya. Cara yang lazim dipakai untuk uji seperti ini adalah melalui cara ‘pilot test’. Dengan cara ini penyelenggara blended learning bisa minta masukan atau saran dari pengguna atau peserta pilot test.
  5. Selenggarakan blended learning dengan baik sambil juga menugaskan instruktur khusus (dosen/guru) yang tugas utamanya melayani pertanyaan siswa, apakah itu bagaimana melakukan pendaftaran sebagai peserta, bagaimana siswa atau instruktur yang lain melakukan akses terhadap bahan ajar, dan lainlain. Instruktur ini juga bisa berfungsi sebagai petugas promosi (public relation) karena yang bertanya mungkin bukan dari kalangan sendiri, tetapi dari pihak lain.
  6. Siapkan kriteria untuk melakukan evaluasi pelaksanaan blended learning. Memang banyak cara bagaimana membuat evaluasi ini, namun Semler (2005) menyarankan sebagai berikut:
    1. Ease to navigate, dalam artian seberapa mudah siswa bisa mengakses semua informasi yang disediakan di paket pembelajaran yang disiapkan di komputer. Kriterianya: makin mudah melakukan akses adalah makin baik.
    2. Content/substance, dalam artian bagaimana kualitas isi instruksional yang dipakai. Misalnya bagaimana petunjuk mempelajari isi bahan ajar, bagaimana bahan ajar itu disiapkan, apakah bahan ajar yang ada sesuai dengan tujuan pembelajaran, dan sebagainya. Kriterianya: makin mendekati isi bahan ajar itu dengan tujuan pembelajaran adalah makin baik.
    3. Layout/format/appearance, dalam artian apakah paket pembelajaran (bahan ajar, petunjuk belajar, atau informasi lainnya) disajikan secara profesional. Kriterianya: makin baik penyajian bahan ajar adalah makin baik.
    4. Interest, dalam artian sampai seberapa besar paket pembelajaran (bahan ajar, petunjuk belajar, atau informasi lainnya) yang disajikan mampu menimbulkan daya tarik siswa untuk belajar. Kriterianya: bila paket pembelajaran yang disajikan mampu menimbulkan siswa untuk terus tertarik belajar adalah makin baik.
    5. Applicability, dalam artian seberapa jauh paket pembelajaran (bahan ajar, petunjuk belajar, atau informasi lainnya) yang disajikan bisa dipraktekkan secara mudah. Kriterianya: makin mudah dipraktekkan adalah makin baik.
    6. Cost-effectiveness/value, dalam artian sampai seberapa murah biaya yang dikeluarkan untuk mengikuti paket pembelajaran tersebut. Kriterianya: semakin murah semakin baik.

 

 

sumber :

Soekartawi, A. Haryono dan F. Librero, (2002), Greater Learning Opportunities Through Distance Education: Experiences in Indonesia and the Philippines. Southeast Journal of Education

McGinnis, M. (2005). Building A Successful Blended Learning Strategy, (http://www.ltimagazine.com/ltimagazin e/article/articleDetail.jsp?id=167425),

Metode Pembelajaran Berbasis Project


pbjl

Penyusunan laporan dan presentasi/publikasi hasil proyek Hasil proyek dalam bentuk produk, baik itu berupa produk karya tulis, karya seni, atau karya teknologi/prakarya dipresentasikan dan/atau dipublikasikan kepada peserta didik yang lain dan guru atau masyarakat dalam bentuk pameran produk pembelajaran.

  1. Penentuan proyek Pada langkah ini, peserta didik menentukan tema/topik proyek berdasarkan tugas proyek yang diberikan oleh guru. Peserta didik diberi kesempatan untuk memilih/menentukan proyek yang akan dikerjakannya baik secara kelompok ataupun mandiri dengan catatan tidak menyimpang dari tugas yang diberikan guru.
  2. Perancangan langkah-langkah penyelesaian proyek Peserta didik merancang langkah-langkah kegiatan penyelesaian proyek dari awal sampai akhir beserta pengelolaannya. Kegiatan perancangan proyek ini berisi aturan main dalam pelaksanaan tugas proyek, pemilihan aktivitas yang dapat mendukung tugas proyek, pengintegrasian berbagai kemungkinan penyelesaian tugas proyek, perencanaan sumber/bahan/alat yang dapat mendukung penyelesaian tugas proyek, dan kerja sama antar anggota kelompok.
  3. Penyusunan jadwal pelaksanaan proyek Peserta didik di bawah pendampingan guru melakukan penjadwalan semua kegiatan yang telah dirancangnya. Berapa lama proyek itu harus diselesaikan tahap demi tahap.
  4.  Penyelesaian proyek dengan fasilitasi dan monitoring guru Langkah ini merupakan langkah pengimplementasian rancangan proyek yang telah dibuat. Aktivitas yang dapat dilakukan dalam kegiatan proyek di antaranya adalah dengan
    1. membaca,
    2.  meneliti,
    3. observasi,
    4. interviu,
    5. merekam,
    6. berkarya seni,
    7. mengunjungi objek proyek, atau
    8.  akses internet. Guru bertanggung jawab memonitor aktivitas peserta didik dalam melakukan tugas proyek mulai proses hingga penyelesaian proyek. Pada kegiatan monitoring, guru membuat rubrik yang akan dapat merekam aktivitas peserta didik dalam menyelesaikan tugas proyek.
  5. Penyusunan laporan dan presentasi/publikasi hasil proyek Hasil proyek dalam bentuk produk, baik itu berupa produk karya tulis, karya seni, atau karya teknologi/prakarya dipresentasikan dan/atau dipublikasikan kepada peserta didik yang lain dan guru atau masyarakat dalam bentuk pameran produk pembelajaran.
  6. Evaluasi proses dan hasil proyek Guru dan peserta didik pada akhir proses pembelajaran melakukan refleksi terhadap aktivitas dan hasil tugas proyek. Proses refleksi pada tugas proyek dapat dilakukan secara individu maupun kelompok. Pada tahap evaluasi, peserta didik diberi kesempatan mengemukakan pengalamannya selama menyelesaikan tugas proyek yang berkembang dengan diskusi untuk memperbaiki kinerja selama menyelesaikan tugas proyek. Pada tahap ini juga dilakukan umpan balik terhadap proses dan produk yang telah dihasilkan.

Continue reading