2006年07月31日

bake:adding "confirm" step

If you need to add "confirm" step in your cakephp script, you can try this:

http://www12.atwiki.jp/nezox/pages/6.html

CakePHPまとめ@Wiki を始めた方がいらっしゃるようです。
参考になりますね。

POST で判別して、

if(@$_POST['mode']=='confirm')
{
if(!$this->Login->validates($this->params['data']))
{
$this->render();
}
else
{
$this->set('form', $this->params['form']);
$this->set('data', $this->params['data']);
$this->render("confirm");
}
}
とするのがミソです。
posted by SDozono at 10:02| ロサンゼルス ☁| Comment(0) | TrackBack(0) | CakePHP Controller | このブログの読者になる | 更新情報をチェックする

2006年07月17日

いちばん簡単な認証システム

CakePHP には、ACL という認証システムが標準で入っています。しかし、ログイン画面やアクセスチェックなどは自前で用意する必要がありますし、データベースでユーザと権限を管理するなど、かなり本格的なものです。

自分が今、作成しているアプリケーションは、少人数(または一人)で管理できればいいものなので、単純にパスワード一つを登録できて、それで全体の認証チェックをしてくれればよい、という程度のものです。

そこで簡単なスクリプトを書いてスニペットに登録してみました。
データベースを使わず、ユーザ名とパスワード一つでアプリケーション全体を守るタイプのものです。ソースを見れば一目瞭然なコードです。

http://cakeforge.org/snippet/detail.php?type=package&id=20

関心を持ってくれたShane Shepherd さんが、CAKE_ADMIN ルーティングの場合にはどうできるか、というアイデアを出してくれました。

http://www.shepherdweb.com/2006/07/14/single-user-admin-area-authentication-with-cakephp/

これを使えば、アプリ名/admin/コントローラ/アクション というadmin専用の形での認証に使えます。

自分でも必要になったのでちょっと調べてみたところ、こういう書き方もできるかな、と思いました。

class AppController extends Controller {

var $components = array(’SdAuth’);

function beforeFilter()
{

//for CAKE_ADMIN(admin) rooting.
if(defined(’CAKE_ADMIN’) && !empty($this->params[’admin’])){
//start admin check.
if($this->SdAuth->isloggedin() == FALSE)
{
//$this->layout = “login”;
***$this->layout = '';
***$this->render('../layouts/login');
***exit();
*など。pm11opさん、ありがとうございます。*
*http://pm.11op.net/2007/12/post-28.php*
} else {
$this->layout = “admin_default”;
}
}

これだと、/admin/ を間にはさんでアクセスした場合にのみ、認証チェックをかけてくれます。
posted by SDozono at 14:38| ロサンゼルス 🌁| Comment(0) | TrackBack(1) | CakePHP Controller | このブログの読者になる | 更新情報をチェックする

2006年07月11日

$this->Set()命令のミステリー

CakePHP はMVC(モデル、ビュー、コントローラ)を分離させる(つまり別々のファイルに分ける)システムです。ですから当然、モデル⇒コントローラ⇒ビューと、データを渡していく必要があります。

仕事を3人で分けたら、必ずそこにコミュニケーションが発生するのと同じです。この3者をつなぐ電話のようなものは何でしょうか。

1)モデルからコントローラへは?

  チュートリアルなどにもかかれていますが、コントローラがモデルの情報を知りたい場合には、
  
class PostsController extends AppController
{
    この中で、
    $result = $this->Post->findAll();
    などのようにして、Postモデルの情報を受け取ることができます。
}

2)コントローラからビューには?

 ここで登場するのは、
 $this->set('変数名', データ); という構文です。コントローラでこれを設定すると、ビューの中でデータが取り出せます。

 注意してほしいのは、

 $this->set('nanika', "これはデータです。"); などのようにすると、

 ビューからは、

echo $nanika;

 として取れるということです。つまり、「set命令でデータをセットすると、ビューの中では変数の名前になる」ということです。また、変数でも配列でも何でも渡すことができます。

Cやその他の言語では、この「データが変数に化ける」という使い方はあまりしないと思うので、最初、戸惑うところかもしれません。また、PHPらしいところをうまく使っていると言っていいかもしれません。CakePHPにはキャッシュの機能もありますので、これと組み合わせると、Smarty などの外部のテンプレートシステムを使用する必要がないほどです。

内部的にはどうやって実現しているかというと、view.php の中に、

extract($___dataForView, EXTR_SKIP);

という文があります。ここでデータを変数に展開しています。

そういえば Ruby には extract に似た関数があるのかな、と思い調査したところ、そんなに簡単ではなさそう?でした。
http://www.html.com/forums/ruby/48892-extract-hash-into-local-variables.html

Ruby の方、Rails では、このあたりがどんな具合になっているんでしょうか……?

*追記*

3)ビュー(送信フォーム)からコントローラには?
これはちょっとヒントだけ書いておきます。考えてみてください。
マニュアルのブログ・チュートリアルを見ると、

function add()
{
  if (!empty($this->data))
  {
    if ($this->Post->save($this->data))
    {
      $this->flash('Your post has been saved.','/posts');
    }
  }
}

とあります。 $this->data の中にデータが入っている場合には、データベースに登録する、ということは……。また、フォーム(ビュー)のほうでは、
<?php echo $html->input('Post/title', array('size' => '40'))?>
と書いてありますね……。

また今度、この辺を詳しく解説してみます。




    
posted by SDozono at 13:11| ロサンゼルス 🌁| Comment(3) | TrackBack(0) | CakePHP Controller | このブログの読者になる | 更新情報をチェックする

2006年07月09日

A question for sd_auth

Dozono,

Thanks for the simple authentication component you developed. It's
perfect for a number of scenarios. I'm new to MVC and to CakePHP.
Is there a way to limit the beforeFilter() Auth Check to the /admin
path? I'm attempting to use CAKE_ADMIN. Also, what is the best way
to implement the logout method?

Thanks,

S.S
----------------------------------------------
Dear S.S.

Thank you for you e-mail.
So far, I haven't tested how to limit the beforeFilter() Auth Check.
But I had thought a same thing. I'm definitely sure we need that kind of technique too.

Your idea sounds a right direction to go.

As for a logout method, I have 'users' table, so

= Model =============================
class UsersController extends AppController
{
  function logout(){
   $this->SdAuth->logout();
   $this->redirect("/index.php");
  }
= View ===============================
<a href="/cake(path of cake)/users/logout">logout</a>
====================================

But I'm not sure if this is the best. Tell us your experiment!

Regards,
S.Dozono

----------------------------------------------
Shunro,

Hey, thanks for the tip! That works great. I think I found a workaround to protect /admin:

change the function in app_controller.php to this:

function adminAuth()
{
// Auth Check.
if($this->SdAuth->isloggedin() == FALSE){
$this->layout = "admin_login";
} else {
$this->layout = "admin";
};
}

notice it is now called "adminAuth()" instead of "beforeFilter()".

Then, in my other controllers, in any method for CAKE_ADMIN I add a call to that function before doing anything:

// This is in pages_controller
function admin_index()
{
$this->adminAuth();
}

I think I could have also gotten your original method to work using a sub-domain for the admin panel like: admin.mysite.com

Regards,

Shane




posted by SDozono at 05:35| ロサンゼルス ☀| Comment(1) | TrackBack(0) | CakePHP Controller | このブログの読者になる | 更新情報をチェックする