我正在尝试覆盖“public function sendCode()”以从 TokenModel 下方的 LoginController 中使用它。
已经做了三倍以上,确认从 LoginController 作为实例加载和调用 TokenModel 是成功的,但是 TokenModel 中不包含“公共函数 sendCode()”。
如果有人知道这里发生了什么并告诉我应该编码什么,那将非常有帮助。
=======================TokenModel=========================
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
class Token extends Model
{
const EXPIRATION_TIME = 15; // minutes
protected $fillable = [
'code',
'user_id',
'used'
];
public function __construct(array $attributes = [])
{
if (! isset($attributes['code'])) {
$attributes['code'] = $this->generateCode();
}
parent::__construct($attributes);
}
/**
* Generate a six digits code
*
* @param int $codeLength
* @return string
*/
public function generateCode($codeLength = 4)
{
$min = pow(10, $codeLength);
$max = $min * 10 - 1;
$code = mt_rand($min, $max);
return $code;
}
/**
* User tokens relation
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo(User::class);
}
/**
* Send code to user
*
* @return bool
* @throws \Exception
*/
public function sendCode()
{
if (! $this->user) {
throw new \Exception("No user attached to this token.");
}
if (! $this->code) {
$this->code = $this->generateCode();
}
try {
app('twilio')->messages->create($this->user->getPhoneNumber(),
['from' => env('TWILIO_NUMBER'), 'body' => "Your verification code is {$this->code}"]);
} catch (\Exception $ex) {
return false; //enable to send SMS
}
return true;
}
/**
* True if the token is not used nor expired
*
* @return bool
*/
public function isValid()
{
return ! $this->isUsed() && ! $this->isExpired();
}
/**
* Is the current token used
*
* @return bool
*/
public function isUsed()
{
return $this->used;
}
/**
* Is the current token expired
*
* @return bool
*/
public function isExpired()
{
return $this->created_at->diffInMinutes(Carbon::now()) > static::EXPIRATION_TIME;
}
}
========================登录控制器=========================
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Token;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Lang;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
}
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return mixed
*/
public function login(Request $request)
{
$this->validateLogin($request);
//retrieveByCredentials
if ($user = app('auth')->getProvider()->retrieveByCredentials($request->only('email', 'password'))) {
$token = Token::create([
'user_id' => $user->id
]);
if ($token->sendCode()) {
session()->set("token_id", $token->id);
session()->set("user_id", $user->id);
session()->set("remember", $request->get('remember'));
return redirect("code");
}
$token->delete();// delete token because it can't be sent
return redirect('/login')->withErrors([
"Unable to send verification code"
]);
}
return redirect()->back()
->withInputs()
->withErrors([
$this->username() => Lang::get('auth.failed'),
]);
}
/**
* Show second factor form
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
*/
public function showCodeForm()
{
if (! session()->has("token_id")) {
return redirect("login");
}
return view("auth.code");
}
/**
* Store and verify user second factor.
*/
public function storeCodeForm(Request $request)
{
// throttle for too many attempts
if (! session()->has("token_id", "user_id")) {
return redirect("login");
}
$token = Token::find(session()->get("token_id"));
if (! $token ||
! $token->isValid() ||
$request->code !== $token->code ||
(int)session()->get("user_id") !== $token->user->id
) {
return redirect("code")->withErrors(["Invalid token"]);
}
$token->used = true;
$token->save();
$this->guard()->login($token->user, session()->get('remember', false));
session()->forget('token_id', 'user_id', 'remember');
return redirect('home');
}
}