乐者为王

Do one thing, and do it well.

用Rails 2.3打造简单记账应用(3)

这次要给应用加上一个认证系统(注册、激活、登录、登出)。当用户输入注册信息时,必须输入有效的邮箱地址,注册成功后,用户并不能立即登录系统,而是要登录注册时输入的邮箱,通过该邮箱内的激活邮件来激活账户。通过这种方式可以防止用户的恶意注册。

restful_authentication是一个支持Rails 2.0的认证系统插件,它为你生成REST风格的认证系统模板,除了提供最基本的用户注册登录登出功能外,还有一个可选的邮件激活功能。只要一个命令,它就为你生成了User模型、管理注册和登录的控制器、相应的视图页面、mailer等等。

安装插件和生成框架代码

1
2
3
script/plugin install git://github.com/technoweenie/restful-authentication.git restful_authentication
script/generate authenticated user sessions --include-activation
rake db:migrate

--include-activation选项决定是否生成向新注册用户发送激活码邮件的代码。

如果你想你的URL看起来更符合惯例一些,那么可以在config/routes.rb中添加:

1
2
3
map.signup '/signup', :controller => 'users', :action => 'new'
map.login '/login', :controller => 'sessions', :action => 'new'
map.logout '/logout', :controller => 'sessions', :action => 'destroy'

因为使用了--include-activation选项,所以还要在config/routes.rb中增加以下映射:

1
2
map.activate '/activate/:activation_code',
             :controller => 'users', :action => 'activate', :activation_code => nil

最后,还需要添加一个observer到config/environment.rb的Rails::Initializer块中:

1
config.active_record.observers = :user_observer

设置ActionMailer,在config/environments/development.rb中添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  :address => "smtp.example.com",
  :port => 25,
  :domain => "example.com",
  :authentication => :login,
  :user_name => "yourname@example.com",
  :password => "yourpassword"
}
config.action_mailer.default_charset = "utf-8"

HOST = "localhost:3000"
ADMINEMAIL = "yourname@example.com"

打开app/models/user_mailer.rb,修改

1
2
3
4
@body[:url]  = "http://YOURSITE/activate/#{user.activation_code}"
@body[:url]  = "http://YOURSITE/"
@subject     = "[YOURSITE] "
@from        = "ADMINEMAIL"

为以下代码:

1
2
3
4
@body[:url]  = "http://#{HOST}/activate/#{user.activation_code}"
@body[:url]  = "http://#{HOST}/"
@subject     = "[#{HOST}] "
@from        = "#{ADMINEMAIL}"

如果出现以下错误信息,那么可能是smtp_settings中的domain没有填写:

1
2
3
4
Net::SMTPSyntaxError (500 Error: bad syntax):
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:679:in 'check_response'
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:652:in 'getok'
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:622:in 'helo'

user_mailer.rb中的ADMINEMAIL必须是一个有效的邮件账号,否则会出现:

1
2
3
4
Net::SMTPFatalError (550 Invalid User):
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:679:in 'check_response'
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:652:in 'getok'
  RAILS_HOME/lib/ruby/1.8/net/smtp.rb:630:in 'mailfrom'

代码下载:https://github.com/dohkoos/qianbao

Comments