NodeJS로 개발하려다가 여러가지 애로사항이 꽃피어서 다시 Laravel로 돌아왔습니다... 역시 서버는 순차프로그래밍이지!-_-

암튼, Laravel사이트에 갔더니 5.0이 나왔더군요. 그래서 또 자세히 보니, HomeStead라는 게 생겼는데(원래 있었는지는 잘 모르겠...), 이것은 손쉽게 개발환경이 셋팅된 가상 서버를 만들어주는 것입니다.

어떤 구조냐면요. Vagrant라는 것이 있는데요. 이것은 이미 만들어진 개발환경을 손쉽게 자신의 PC에 명령어 몇 줄로 올리는 것입니다. 이 개발환경을 Laravel 환경에 맞게 구성한 것이 Laravel HomeStead입니다. 

사실 PHP를 셋팅하려면 apache or nginx 설치하고, php도 설치하고, 서로 환경설정해서 연동도 하고, MySQL도 설치하고, 필요하면 캐시 서버인 Memcached or Redis도 설치하고, 여간 쉬운 일이 아니죠. 그리고, 보통 Windows 또는 OSX에서 작업을 많이 하기 때문에 실제 리얼서버는 대부분 리눅스계열이라 환경이 틀려서 제대로 동작하지 않을 수도 있지요.

Vagrant 사이트입니다. 여기서 그냥 Getting Started만 따라해도 몇 분만에 우분투 서버를 띄울 수 있어요.
https://www.vagrantup.com/


Laravel homeStead는?

Ubuntu 14.04
PHP 5.6
HHVM
Nginx
MySQL
Postgres
Node (With Bower, Grunt, and Gulp)
Redis
Memcached
Beanstalkd
Laravel Envoy
Fabric + HipChat Extension
Blackfire Profiler

를 포함하고 있대요. 그래서 설치만 하면 우분투 환경에 nginx위에 돌아가는 Laravel이 이미 셋팅이 되어 있는 것이죠.
아래 사이트에서 설치 및 셋팅이 잘 나와있어요.

http://laravel.com/docs/5.0/homestead

간단하게 정리를 하면 아래와 같습니다(일단 맥용 기준인데 윈도우즈용도 매우 흡사할 것이에요).


1. VirtualBox & Vagrant 설치

https://www.virtualbox.org/wiki/Downloads
http://www.vagrantup.com/downloads.html


2. Vagrant에 Laravel/HomeStead 추가.

이 작업은 vagrant에 가상머신 다운로드해서 추가해놓는 작업 같습니다. 

vagrant box add laravel/homestead


3. homestead 설치

두 가지 방식이 있는데, 하나는 git을 이용한 방식이고, 하나는 composer를 이용한 방식입니다. 사실 composer로 설치하는 homestead가 뭐 별거 없는 게 vagrant를 래핑한 것입니다. 그래서 git으로 Vagrant파일 받고, vagrant로 써도 무관합니다.

수동으로 git 설치 방법

git clone으로 원하는 위치에 받은 뒤, init스크립트를 호출해주면 설치와 셋팅이 완료됩니다. 

git clone https://github.com/laravel/homestead.git Homestead
cd Homestead
bash init

그러면 ~/.homestead/Homestead.yaml 파일이 생기는데, 이 파일의 설정으로 자신의 PC와 가상머신과 연결할 경로를 지정하거나 SSH키 위치 셋팅 등을 할 수 있어요.

composer 이용방법

아래 명령어로 설치를 하면 homestead command를 사용할 수 있는데, 이것을 이용하면 쉽게 초기화하고 쉽게 edit를 띄울 수 있고, 쉽게 Vagrant를 up할 수 있습니다.

composer global require "laravel/homestead=~2.0"
homestead init

이것도 init을 하면 위와 같은 경로에 설정파일이 생겨요.


4. Laravel 경로 지정

Homestead.yaml의 기본 경로는 ~/Code 입니다. 자신의 Laravel위치로 바꿔주면 됩니다. 그러면 로컬에서 수정하고 확인은 Homestead로 하면 됩니다. laravel은 설치했다는 과정하에....

mkdir ~/Code
cd Code
laravel new Laravel

그러면 설정에 기본셋팅에 맞는 위치에 Laravel이 생깁니다. 바로 서버를 띄워서 확인할 수 있어요. 물론 원하는 위치로 셋팅을 바꿀 수도 있어요. 


5. ssh 설정

이건 아마 기본적으로 ~/.ssh에 rsa를 만들었다면 따로 안해줘도 될겁니다. 다른 키를 쓰고 싶다면 Homestead.yaml에 다르게 설정해야 합니다.


6. 호스트 잡기

/etc/hosts파일에 아까 Homestead.yaml에 정의된 sites주소로 잡는 겁니다. 그 주소로 들어오면 Laravel을 열도록 nginx가 설정되어 있습니다.

/etc/hosts

# homestead
192.168.10.10  homestead.app


7. 실행하기

git으로 설치했다면 Homestead 폴더로 가서 Vagrant up하면 됩니다.
composer로 설치했다면 그냥 아무 위치에서 homestead up하면 됩니다.


8. 확인하기 

http://homestead.app/
Laravel5가 보이면 성공...


근데, 쓰고 나니까 뭔가 셋팅하는 게 복잡해 보이는데 그렇게 복잡하진 않아요. 실제 일일이 로컬에 개발환경 셋팅하는 것보단 이 방식이 더 나아보입니다. PC를 깨끗하게 쓰고 싶은 사람들은 로컬에 뭔가 따로 설치하지 않아도 되니까 좋기도 하구요.

 
Posted by 머드초보
,
 

구글앱엔진에서 php를 preview 맛보기로 제공을 하네요.

https://developers.google.com/appengine/docs/php/gettingstarted/introduction

여기 문서를 따라한건데, 얘는 콘솔로했는데, 보니까 Launcher로 하면 더 편하니까 런쳐로 설명할게요.


1. 프로젝트 생성.

https://cloud.google.com/console#/project
여기가서 CreateProject를 해야해요. Project Name은 원하는 것으로 쓰고, Project ID를 유니크한 것으로 써야해요. 저는 mudchobo-php라고 썼어요. 생성하면 뭔가가 생겨요.


2. 필요한 프로그램 설치 - Python 2.7.x, Google App Engine SDK

파이선 다운로드 : http://www.python.org/download/
Google App Engine SDK : https://developers.google.com/appengine/downloads


3. Google App Engine Launcher

위에 대로 설치하면 Google App Engine Launcher가 설치돼요. 실행해요.
메뉴에 File -> Create New Application하고, Application Name에 구글클라우드콘솔에서 생성한 Application ID를 넣고, Parent Directory에는 원하는 경로를 지정해요. 이 안에 새로운 폴더로 프로젝트가 생성돼요. runtime은 php로 하고, port는 원하는 포트로 지정하고 Create하면 해당 폴더에 프로젝트가 생겨요. 간단히 필요한 app.yaml과 main.php, favicon.ico만 생겨요. 다 끝났어요. 실행하면 끝나요.



4. 실행

아이콘 중에 Run이라고 있는데, 이걸 클릭하면 서버가 실행이 돼요. 그러고 그냥 localhost:8080으로 접속하면 Hello World!가 떠요. 그럼 끝난거에요. 이제 개발하면 돼요.


5. 구글계정 Users 서비스.

php도 python과 java처럼 구글계정 연동을 매우 손쉽게 제공해요.
main.php

<?php
       require_once 'google/appengine/api/users/UserService.php' ;
       use google \ appengine \api \ users \User ;
       use google \ appengine \api \ users \UserService ;
       $user = UserService ::getCurrentUser() ;

       if ($user ) {
             echo 'Hello, ' . htmlspecialchars ( $user -> getNickname());
       } else {
             header ( 'Location: ' . UserService ::createLoginURL ($_SERVER [ 'REQUEST_URI' ])) ;
       }

소스를 보면 알겠지만, 그냥 UserService라는 클래스를 가져와서 유저값이 있으면 유저 닉네임을 보여주고 없으면 로그인으로 이동시켜요.


이게 로컬에서는 이렇게 나오는데, 실제로 Deploy(배포)를 하면 구글로그인으로 로그인이 돼요.


6. 폼

main.php에 아래와 같이 또 추가해요.

<html>
    <body>
        <?php
            if (array_key_exists('content', $_POST)) {
                echo "You wrote:<pre>\n";
                echo htmlspecialchars($_POST['content']);
                echo "\n</pre>";
            }
        ?>
        <form action="/sign" method="post">
            <div><textarea name="content" rows="3" cols="60"></textarea></div>
            <div><input type="submit" value="Sign Guestbook" /></div>
        </form>
    </body>
</html>

소스를 보면 알겠지만, 그냥 폼값 읽어서 보여주는거에요.


7. static파일

php 굳이 거쳐도 되지 않는, css나 js파일 같은 것들을 그냥 뿌려주려고 하려고 해요.
app.yaml을 수정해야해요.

- url: /stylesheets
  static_dir: stylesheets

/stylesheets라는 url은 stylesheets에 있는 것을 그대로 내려준다는 거에요.

main.css파일을 stylesheets폴더를 만들고 생성해보아요.

body {
  font-family: Verdana, Helvetica, sans-serif;
  background-color: #DDDDDD;
}

백그라운드값을 바꿔보아요.
main.php에 head부분에 css를 추가해보아요.

<head>
    <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
</head>

다 만든 결과에요.


8. 배포

Google App Engine Launcher에서 Deploy를 눌러요. Email과 Password를 입력해요. 구글계정이에요. 그럼 이상한 콘솔창 하나 뜨더니 그냥 올라가요. 매우 간편해요!

 
Posted by 머드초보
,
 
1. MongoDB 설치

OS별 설치방법이 공식홈페이지에 잘 나와있습니다.
http://www.mongodb.org/display/DOCS/Quickstart

저는 Windows라서 다운로드 받고, 압축 푼 다음에 \data\db 폴더 만들고, mongod 실행하니까 바로 되더라구요. 이렇게 손쉽게 설치되는 DB라니.....ㅠㅠ


2. php에 MongoDB Driver 설치

이것도 공식홈페이지에 잘 나와있네요.
http://www.mongodb.org/display/DOCS/PHP+Language+Center

https://github.com/mongodb/mongo-php-driver/downloads 여기서 Driver를 다운로드 받아서 dll파일을 extension에 추가만 해주면 됩니다.
압축 풀면 vc6~9별로 나눠져있는데, apache 버전에 맞춰서 dll을 복사해야합니다. 안그러면 에러납니다.
extension=php_mongo.dll


3. CodeIgniter 설치

php쪽 프레임워크는 처음 써보는데, 코드이그나이터가 제일 괜춘한가보네요. 회사에서 쓰려고 알아보다 보니 여기까지 왔네요.

공식홈페이지에서 다운로드 받고, apache 경로에 압축풀어주면 됩니다. 저는 localhost/codeigniter에 풀었습니다.
http://codeigniter.com/downloads/

저는 config에서 base_url과 index_page를 수정했습니다.
/application/config/config.php
$config['base_url']    = 'http://localhost/codeigniter/';
$config['index_page'] = '';


그리고, localhost/codeigniter/index.php/~~~ 이런 형태가 되는데, index.php를 없애고 싶으면 이렇게 하면 되는 듯 합니다.
압축푼 폴더에 즉, codeigniter에 .htaccess 파일을 만들어서
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /codeigniter/index.php/$1 [L]

라고 쓰면 되는 듯.
여기 참고 -> http://codeigniter.com/user_guide/general/urls.html


4. MongoDB CodeIgniter용 library 다운로드 및 설치

Mongo클래스를 CodeIgniter에 맞게 잘 래핑한 클래스가 있습니다.
https://github.com/kyledye/MongoDB-CodeIgniter-Driver

여기서 다운로드 하면, Config폴더랑 libraries폴더에 mongo_db.php파일이 있습니다.
config폴더에 있는 것은 /application/config/ 폴더로, libraries폴더에 있는 것은 /application/libraries/ 폴더로 복사합니다.

config에 있는 mongo_db.php파일은 각자 설정에 맞게 고쳐줘야 합니다.


5. CodeIgniter Model 만들기

생성자에서 mongo_db library를 로드합니다. 그리고, 리스트를 가져오는 getList, 글쓰는 write, 삭제하는 delete함수를 만들었습니다.
이 라이브러리를 보니까, 가져오기전에 조건문(where, orderby 등등)을 미리 셋팅하고, get이나 delete 등을 호출하는 방식입니다. 아래 클래스를 보시면 매우 쉽습니다.

/application/models/board_model.php
<?php
class Board_model extends CI_Model
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library("mongo_db");
    }
   
    public function getList()
    {
        $this->mongo_db->order_by(array("_id"=>-1));
        $data = $this->mongo_db->get("board");
        return $data;
    }
   
    public function write($name, $contents)
    {
        $this->mongo_db->insert("board", array("name"=>$name, "contents"=>$contents));
    }
   
    public function delete($id)
    {
        $this->mongo_db->where(array("_id"=>new MongoId($id)));
        $this->mongo_db->delete("board");
    }
}
?>


6. CodeIgniter Controller 만들기

리스트를 보여주는 index와 글쓰기 write, 글삭제 delete가 있습니다.

/application/controllers/board.php
class Board extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->model("board_model");
        $this->load->helper('url');
    }
   
    public function index()
    {
        $data["list"] = $this->board_model->getList();
        $this->load->view("board", $data);
    }
   
    public function write()
    {
        $name = $this->input->post("name", true);
        $contents = $this->input->post("contents", true);
        $this->board_model->write($name, $contents);
        redirect("/board/index", "refresh");
    }
   
    public function delete()
    {
        $id = $this->input->post("id", true);
        $this->board_model->delete($id);
    }
}
?>

7. Condeigniter view 만들기

위에 Controller에서 index()함수를 보면 board라는 view를 호출하게 되어있습니다. board라는 view를 만듭니다.

/application/views/board.php
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
        <script>
            $(document).ready(function(){
                $(".btnDelete").click(function(){
                    var _id = $(this).attr("_id");
                    $.post("delete", {id:_id}, function(){
                        alert("삭제되었습니다.");
                        window.location.href = "index";
                    });
                });
            });
        </script>
    </head>
    <body>
        <form action="write" method="post">
            <input type="text" name="name" /><br />
            <textarea name="contents"></textarea>
            <input type="submit" value="글쓰기" />
        </form>
       
        <ul>
        <?php foreach ($list as $board):?>
            <li>
                <?php echo $board["name"];?> : <?php echo $board["contents"];?>
                <input class="btnDelete" type="button" _id="<?php echo $board["_id"]?>" value="삭제" />
            </li>
        <?php endforeach;?>
        </ul>
    </body>
</html>

지금 jquery ajax랑 form전송이 짬뽕이 되었는데, 그냥 그러려니 하세요-_-
어쨌든 글 작성 시에는 write를 호출하고, 삭제 시에는 delete를 호출하면 잘 작동합니다. MongoDB도 잘 작동을 해서 입력 삭제가 잘 되네요.



PS. 뭔가 작성하면서 빠뜨린 기분이네...
 
Posted by 머드초보
,
 
미투데이도 얼른 OAuth기반으로 바꿨으면 좋겠네요.
인증 방식은 비슷하긴 하지만, access_token요청하는 부분 같은 게 없어서 callbackurl로 사용자api키를 받게 되는군요. 보안상 안좋을 것 같은...-_-

그리고, 언제까지 스프링노트에 표시를 할 것인지가 의문입니다.
트위터가 OpenAPI를 참 잘해놔서 그런지 굉장히 많은 서비스들이 튀어나오고 있습니다. 이점은 미투데이에서도 얼른 OpenAPI에 힘을 쓰시는 게...^^

api페이지입니다.
http://codian.springnote.com/pages/86001

요청절차는 이러합니다. 물론 여기가면 더 자세히 나와있습니다ㅠㅠ(웹인증기반 기준!)
http://codian.springnote.com/pages/1645274
1) api키를 발급받습니다.
2) 해당 api키로 인증 토큰을 얻습니다.
3) 그 토큰으로 인증url로 이동시킵니다.
4)사용자가 로그인 하면 지정한 callback페이지로 사용자키를 던져줍니다.
5) 사용자키로 글을 쓰면 됩니다.


1. 일단 API키 발급

http://me2day.net/me2/app/key/list
여기서 새 애플리케이션 키 발급한다음에 등록합니다. 그리고 등록된 키에서 설정을 누르면 웹기반인지 데스크탑기반인지 선택하는데, 웹기반이면 callback주소를 입력받습니다. 이 callback주소는 인증 후에 사용자키를 받는 url이 됩니다.

2. 해당api키로 인증토큰 얻기
config.php파일
[code]<?php
define('A_KEY', '발급받은 api키');
?>[/code]
index.php
[code]<?php
    require_once("config.php");
    $result = json_decode(file_get_contents("http://me2day.net/api/get_auth_url.json?akey=" . A_KEY));
    print_r($result);
?>
<!doctype html>
<html>
    <head>
        <meta charset="EUC-KR">
        <title>미투데이 인증 후 글쓰기</title>
      </head>
    <body>
        <br />
        <a href="<?php echo $result->url ?>">미투데이 인증하기</a>
      </body>
</html>[/code]
php에서 http://me2day.net/api/get_auth_url.json를 요청해서 token을 받습니다. 그러면 인증url이 같이 떨어집니다. 그 url로 이동하게 되면 아래와같이 로그인하는 화면이 나옵니다.
사용자 삽입 이미지
여기서 로그인하고 인증하면 1번에서 지정한 callbackurl로 이동하게 됩니다.

3. callback url에서 데이터받고 글쓰기 폼생성

callback.php
[code]<?php
    require_once("config.php");
   
    $token = $_GET["token"];
    $user_id = $_GET["user_id"];
    $user_key = $_GET["user_key"];
    $result = $_GET["result"];
   
    // 세션저장
    session_start();
    $_SESSION["user_id"] = $user_id;
    $_SESSION["user_key"] = $user_key;
   
    // 인증이 확실한지 확인
    $authKey = "12345678" . md5("12345678" . $user_key);
    $result = file_get_contents("http://me2day.net/api/noop?uid={$user_id}&ukey={$authKey}&akey=" . A_KEY);
?>
<!doctype html>
<html>
    <head>
        <meta charset="EUC-KR">
        <title>미투데이 인증 콜백</title>
        <script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function(){
                $("#btnPost").click(function(){
                    var body = $("#inputPost").val();
                    if (body.length < 1){
                        alert("글입력해요!");
                        return;
                    }
                    $.getJSON("post.php?callback=?", {body:body}, function(data){
                        alert("글쓰기 성공 = " + data.result);
                    });
                });
            });
        </script>
      </head>
    <body>
        <?php echo $result ?><br/>
        <input type="text" id="inputPost" name="inputPost" /><br />
        <input type="button" id="btnPost" name="btnPost" value="글쓰기"/>
      </body>
</html>[/code]
보면 user_id랑 user_key를 세션에 저장합니다. 만약 자신의 사이트에서 미투데이인증과 통합을 원한다면 api키를 데이터베이스같은 영속적인 것에 저장하고 쓰는 것이 좋습니다. 그럼 따로 인증같은 것을 하지 않아도, 자신의 사이트만 인증을 해도 글을 쓸 수 있으니까요^^
나중에 api_key값이 바뀐다고 해도, noopapi를 호출해서 인증이 정확한지 확인 후 정확하지 않으면 다시 인증받으면 되니까요^^

user_id랑 user_key만 있으면 이제 글을 쓸 수 있으므로, http://me2day.net/api/noop를 호출해서 유효한지 확인을 합니다. 이제부터 인증받은 api들은 uid와 ukey와 akey를 같이 파라메터에 붙여서 호출해야합니다.
uid는 사용자 아이디, ukey는 임의8자리숫자 + md5(임의8자리숫자 + 사용자키), akey는 api키를 넣으면 됨!

4. 글쓰기
post.php
[code]<?php
    require_once("config.php");
   
    $body = $_GET["body"];
    $callback = $_GET["callback"];
   
    session_start();
    $user_id = $_SESSION["user_id"];
    $user_key = $_SESSION["user_key"];
   
   
    // 인증이 확실한지 확인
    $authKey = "12345678" . md5("12345678" . $user_key);
    $result = file_get_contents("http://me2day.net/api/create_post/{$user_id}.json?uid={$user_id}&ukey={$authKey}&akey=" . A_KEY . "&post[body]={$body}");
   
    header("Content-type: application/json");
    echo "{$callback}({'result':'{$result}'})";
?>[/code]
그냥 api문서대로 호출하면 됨!

테스트 url~
mudchobo.tomeii.com/test/me2daytest/

나중에 php용 라이브러리를 만들어봐야겠다...
 
Posted by 머드초보
,
 
트위터 공식API홈페이지에 가면 PHP용 OAuth라이브러리가 2개가 있는데요. 두개중에 이게 더 나은 것 같아서...

트위터 공식api홈페이지 - http://dev.twitter.com/

OAuth라는 게 2년전에 삽질했던 것이 기억나네요.
트위터도 이 방식으로 인증을 하게 되는데요. 간단하게 동작원리를 설명하면......

1. 연동할 어플리케이션을 등록합니다.
2. 등록하게 되면 Consumer key와 Consumer secret을 발급받습니다.
3. 명시된 Request Token url로 이 키를 이용해 요청하게 되면 인증 url로 가서 이 어플에서 계정접근을 허용할 것인지 묻습니다.
4. 그리고, 허용하게 된다면 Access Token url로 이동해 Access Token을 발급 받습니다.
5. 이 받게 된 AccessToken을 이용해서 해당 어플리케이션은 글쓰고, 정보를 불러올 수 있게 됩니다.

이런 일련의 과정이 있지만, LIbrary가 있으면, 이딴거 몰라도 됩니다-_- 라이브러리가 다 알아서 하니까-_-

일단 앱을 등록합니다.
http://dev.twitter.com/apps/new
application type은 browser로 하고, callback url은 access_token까지 다 받은 다음에 우리 웹사이트로 돌아오기 위한 콜백url을 지정하는 것입니다.
등록을 한 다음에, 해당 애플리케이션의 detail을 보게 되면 consumer key랑 consumer secret이 있습니다.

그리고 라이브러리를 받습니다.
http://github.com/abraham/twitteroauth/downloads
그리고 파일들을 통째로 서버에 올립니다.
그리고, config.php파일을 수정합니다.
consmuer_key랑 consumer_secret을 위에서 등록한 앱의 키값을 등록!
callback은 인증을 하고 accesstoken을 얻은 뒤, 우리 앱으로 돌아올 때 callback url을 지정합니다. 그대로 올렸다면 폴더에 callback.php가 있기 때문에 http://localhost/callback.php가 됨!

그리고, 이제 localhost/index.php를 열고, Sign in with Twitter 클릭하면...
사용자 삽입 이미지
수락하면 대충 이런 데이터를 받습니다.
사용자 삽입 이미지

소스를 보게 되면 callback.php에서 AccessToken을 요청해서 받아오게 되는데, AccessToken과 AccessTokenSecret값만 있으면 글을 쓰거나 정보를 가져올 수 있게 됩니다.
이것을 자신의 사이트에 적용을 하게 된다면 db에다가 저장해놓고 쓰게 된다면, 우리사이트의 인증만으로도 트위터에 글을 쓸 수 있게 됩니다.
인증을 취소할 경우를 대비해서 account/verify_credentials api를 요청해 인증이 살아있는지 확인을 해야합니다.
[code]$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']);[/code]
이렇게 connection객체만 가지고 있으면
[code]$connection->post('statuses/update', array('status' => date(DATE_RFC822)));[/code]
이런 형태로 api를 호출해서 데이터를 가져올 수 있습니다.
 
Posted by 머드초보
,