javascript - 如何给被视作为静态资源的spa加上csrf保护?
程序员文章站
2022-04-14 16:27:28
...
最近我在使用
react
+react-router
开发spa,后台使用的是yii2
。nignx
设置的是当404
就返回index.html
。但是这样子有个问题是,我没有办法使用csrf
的保护,这样子要怎么解决呢?
我看到了一个网站使用的技术栈和我的差不多,我看了它是在head标签上面写了一个含有token
值的meta标签,而它的每一个请求都会将这个token
作为header
的值发回去。这样子要怎么做?要怎么将token
值渲染到这个index.html
里头?
回复内容:
最近我在使用react
+react-router
开发spa,后台使用的是yii2
。nignx
设置的是当404
就返回index.html
。但是这样子有个问题是,我没有办法使用csrf
的保护,这样子要怎么解决呢?
我看到了一个网站使用的技术栈和我的差不多,我看了它是在head标签上面写了一个含有token
值的meta标签,而它的每一个请求都会将这个token
作为header
的值发回去。这样子要怎么做?要怎么将token
值渲染到这个index.html
里头?
ajax 提交的
$.ajax({
url: 你的url
type:依什么方式
dataType:数据类型
data :
headers:{'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') ? $('meta[name="csrf-token"]').attr('content') : ''},
beforeSend:function(msg){
alert('等待回调');
},
})
将输出部分放在header头里
getRequest()->isPost()) {
// |
// | try {
// | ##验证TOKEN
// | NoCSRF::check( 'csrf_token', $_POST, true, 60*10, false ); //60*10为10分钟(null为不验证时间)
// | $result = 'CSRF check passed. Form parsed.';
// | //$this->getRequest()->getPost('field');
// | echo $result;
// | } catch ( Exception $e ) {
// | echo $e->getMessage() . ' Form ignored.';
// | }
// | } else {
// | #生成TOKEN
// | $token = NoCSRF::generate( 'csrf_token' );
// | $this->getView()->assign('token', $token);
// | $this->getView()->display('页面');
// | }
// | // 前端
// |
// +----------------------------------------------------------------------
class NoCSRF
{
protected static $doOriginCheck = false;
/**
* Check CSRF tokens match between session and $origin.
* Make sure you generated a token in the form before checking it.
*
* @param String $key The session and $origin key where to find the token.
* @param Mixed $origin The object/associative array to retreive the token data from (usually $_POST).
* @param Boolean $throwException (Facultative) TRUE to throw exception on check fail, FALSE or default to return false.
* @param Integer $timespan (Facultative) Makes the token expire after $timespan seconds. (null = never)
* @param Boolean $multiple (Facultative) Makes the token reusable and not one-time. (Useful for ajax-heavy requests).
*
* @return Boolean Returns FALSE if a CSRF attack is detected, TRUE otherwise.
*/
public static function check( $key, $origin, $throwException=false, $timespan=null, $multiple=false )
{
$session = Session::getInstance();
if ( !$session->has( 'csrf_' . $key ) )
if($throwException)
throw new \Exception( 'Missing CSRF session token.' );
else
return false;
if ( !isset( $origin[ $key ] ) )
if($throwException)
throw new \Exception( 'Missing CSRF form token.' );
else
return false;
// Get valid token from session
$hash = $session->get('csrf_' . $key);
// Free up session token for one-time CSRF token usage.
if(!$multiple)
$session->forget('csrf_' . $key);
// Origin checks
if( self::$doOriginCheck && sha1( $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'] ) != substr( base64_decode( $hash ), 10, 40 ) )
{
if($throwException)
throw new \Exception( 'Form origin does not match token origin.' );
else
return false;
}
// Check if session token matches form token
if ( $origin[ $key ] != $hash )
if($throwException)
throw new \Exception( 'Invalid CSRF token.' );
else
return false;
// Check for token expiration
if ( $timespan != null && is_int( $timespan ) && intval( substr( base64_decode( $hash ), 0, 10 ) ) + $timespan put('csrf_' . $key, $token);
return $token;
}
/**
* Generates a random string of given $length.
*
* @param Integer $length The string length.
* @return String The randomly generated string.
*/
protected static function randomString( $length )
{
$seed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijqlmnopqrtsuvwxyz0123456789';
$max = strlen( $seed ) - 1;
$string = '';
for ( $i = 0; $i