之前用symfony3.4,最近上手symfony5发现加入了很多新特性,搭配easyadminBundle、api-platform这些用起来感觉简直如有神助,瞬间爱了。

不过api-platform还没太弄明白,有用这个的可以给分享下文档,官网文档好多地方说的太简略了。|||

面记一些使用时遇到的小问题:

ps:安装直接按文档composer就行,这里就跳过了;

附:

  1. 官网文档
  2. Symfony 5 快速开发(官网中文版)

0、环境

4.4版本通过.env.local.php配置,通过.env.local.php的APP_ENV字段选择时prod还是dev环境,可以添加其他变量。

1、配置

  • 配置mysql

文档说配置到 /config/doctrine.yml

实际上doctrine.yml又读取了根目录下的.env文件的DATABASE_URL的值,所以可以直接对.env的DATABASE_URL配置。

# DATABASE_URL=mysql://username:password@127.0.0.1:3306/dbname?serverVersion=5.7
# 我的数据库没有密码,所以:后面直接跟了@ip:port
DATABASE_URL=mysql://root:@127.0.0.1:3306/fbm?serverVersion=5.7

2、通过symfony的security实现用mysql用户表登录

先说步骤,后面依次细说:

  1. 创建user entity类实现UserInterface并把它更新到数据库(可以使用命令创建entity:php bin/console make:entity)
  2. 把user类配置为用户提供者,并配置密码加密算法
  3. 创建防火墙认证器(用于登录验证等… 使用命令:php bin/console make:auth)
  4. 给数据库的user表添加用户
  5. 测试登录

1、依次执行:

# 创建enity并根据提示添加usernam、password、roles、salt等字段
# tips:roles建议array类型
php bin/console make:entity # 把enity更新到数据库,最后加上--force换成--dump-sql可以打印出将要执行的sql
php bin/console doctrine:schema:update --force # 创建完entity会看到提示:
# Next: When you're ready, create a migration with php bin/console make:migration
# !!!千万别用doctrine:migrations:migrate这个命令!!!
# php bin/console doctrine:migrations:migrate命令不会修改表的列,还会删除数据库里有的但Entity目录下没有对应类的表,别问我怎么知道的|||

2、在config/package/security.yml的security添加如下配置:

    providers:
users_in_memory: { memory: null }
users:
entity:
# 这个entity类用来提供用户
class: 'App\Entity\User'
# the property to query by - e.g. username, email, etc
property: 'username' encoders:
# use your user class name here
App\Entity\User:
# Use native password encoder 配置密码加密算法
# This value auto-selects the best possible hashing algorithm
# (i.e. Sodium when available).
algorithm: sha256
encode_as_base64: true
iterations: 1 # 循环次数

3、执行如下命令创建验证器:


php bin/console make:auth # 以下是输出内容,根据提示按实际情况填写就好。。。 What style of authentication do you want? [Empty authenticator]:
[0] Empty authenticator
[1] Login form authenticator
> 1
1[K The class name of the authenticator to create (e.g. AppCustomAuthenticator):
> LoginFormAuthenticator #### 验证器类名 Choose a name for the controller class (e.g. SecurityController) [SecurityController]:
> Enter the User class that you want to authenticate (e.g. App\Entity\User) [App\Entity\Us
> Which field on your App\Entity\User class will people enter when logging in? [username]:
[0] id
[1] username
[2] email
[3] password
[4] roles
[5] salt
[6] created_at
[7] updated_at
> Do you want to generate a '/logout' URL? (yes/no) [yes]:
> created: src/Security/LoginFormAuthenticator.php
updated: config/packages/security.yaml
created: src/Controller/SecurityController.php
created: templates/security/login.html.twig Success!

修改验证器类的checkCredentials方法为:

// src/Security/LoginFormAuthenticator.php

    public function checkCredentials($credentials, UserInterface $user)
{
return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
}

其他两步骤就不细说了。

3、easyAdmin bundle创建的用户记录密码没加密的问题

要解决这个问题,可以:--- more》

  1. 改写user entity的setPassword方法为(github的大佬说这种方法破环了封装,我:挺适合我|||):


    public function setPassword(string $password): self
    {
    global $kernel;
    if (method_exists($kernel, 'getKernel'))
    $kernel = $kernel->getKernel();
    $this->password = $kernel->getContainer()->get('security.password_encoder')->encodePassword($this, $password);
    return $this;
    }
  2. 或者实现AdminController和如下关键的几个方法,并且将config/route/easy_admin.yml做如下配置:
easy_admin_bundle:
resource: 'App\Controller\AdminController'
prefix: /admin
type: annotation
<?php

namespace App\Controller;

use App\Entity\User;
use Symfony\Component\Security\Core\Encoder\EncoderFactory;
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
use EasyCorp\Bundle\EasyAdminBundle\Controller\EasyAdminController;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; class AdminController extends EasyAdminController
{
protected function persistUserEntity($user)
{
$encodedPassword = $this->encodePassword($user, $user->getPassword());
$user->setPassword($encodedPassword); parent::persistEntity($user);
} protected function updateUserEntity($user)
{
$encodedPassword = $this->encodePassword($user, $user->getPassword());
$user->setPassword($encodedPassword); parent::updateEntity($user);
} private function encodePassword($user, $password)
{
$passwordEncoderFactory = new EncoderFactory([
// 这里的sha256以及后面的参数要和security.yml里的配置相同,否则加密后登录验证通不过
User::class => new MessageDigestPasswordEncoder('sha256',true,1)
]); $encoder = $passwordEncoderFactory->getEncoder($user); return $encoder->encodePassword($password, $user->getSalt());
} }

4、文件上传,从Request中获取文件和文件名等信息

  • $file是一个Symfony\Component\HttpFoundation\File\File\File类的对象,File类有提供move方法,用它就可以直接移动接收到的文件了。
  • 至于大文件分片上传,需要自己实现接收/合片逻辑。
//文档: https://symfony.com/doc/current/controller/upload_file.html
$file = $request->files->all()['file'] // 获取文件名:
$file->getClientOriginalName()

5、jwt登录/auth

<?php

namespace App\Controller;

use App\Entity\ProjectGroup;
use App\Entity\Role;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; use Doctrine\ORM\EntityManagerInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface; class SecurityController extends AbstractController
{
/**
* @Route("/auth", methods={"POST"})
* api login auth
* */
public function auth(Request $request, JWTTokenManagerInterface $JWTManager, UserPasswordEncoderInterface $passwordEncoder, AuthenticationSuccessHandler $authSuccessHandler)
{
$params = count($request->request->all()) > 0 ? $request->request->all() : json_decode($request->getContent(), true);
$user = $this->em->getRepository(User::class)->findOneBy(array('username' => $params['username'])); if(!$user){
return $this->json(['message' => '用户名或密码错误'], Response::HTTP_BAD_REQUEST);
} if(!$passwordEncoder->isPasswordValid($user, $params['password'])){
return $this->json(['message' => '用户名或密码错误'], Response::HTTP_BAD_REQUEST);
} $jwt = $JWTManager->create($user);
// $tokenStorage->set($jwt); $user->setApiToken($jwt);
$this->em->flush(); return $this->json(array(
'token' => $jwt,
'id' => $user->getId(),
'username' => $user->getUsername(),
'email' => $user->getEmail(),
'roles' => $user->getRoles(),
)); // return $this->json(['token' => $JWTManager->create($user)]);
}
}

这些都是经过好几天的时间摸索出来的 : ( 。。|||,当然,搜索引擎帮了很多忙。)

symfony5初体验:doctrine、配置、文件上传、jwt登录/auth等常见问题的更多相关文章

  1. 体验三大JavaScript文件上传库(Uppy.js/Filepond/Dropzone)

    最近发现了一个高颜值的前端上传组件Uppy.js,立即上手体验了一波,感觉还不错.然后又看到同类型的Filepond以及Dropzone.js,对比体验了一下,感觉都很优秀,但是在体验过程中,都遇到了 ...

  2. xshell配置---文件上传命令rz和下载命令sz

    1.下载安装包 方法一:手动下载安装 1)下载安装包:lrzsz-0.12.20.tar.gz 官网下载地址:http://www.ohse.de/uwe/releases/lrzsz-0.12.20 ...

  3. maven3.6.1-02初体验及jar包上传

    安装当前最新版本的nexus,安装教程网上搜,不多说了. 因为nexus3x版本没有2x版本中内置的3rd_part,所以不能在界面中上传jar包,必须使用maven的命令行.  添加第三方仓库,名字 ...

  4. SpringMVC常用配置-文件上传-基于Servlet 3.0

    [2] http://www.cnblogs.com/weilu2/p/springmvc_MultipartConfigElement_tomcat_webapps_work.html

  5. JavaScript进阶(九)JS实现本地文件上传至阿里云服务器

    JS实现本地文件上传至阿里云服务器 前言 在前面的博客< JavaScript进阶(八)JS实现图片预览并导入服务器功能>(点击查看详情)中,实现了JS将本地图片文件预览并上传至阿里云服务 ...

  6. springmvc 文件上传(粘贴即用)

    这里记录下,方便以后复制粘贴. maven配置 <dependency> <groupId>commons-fileupload</groupId> <art ...

  7. springmvc文件上传示例

    首先要导包,用的的包是: commons-fileupload-*.*.*.jar commons-io-*.*.jar *号代表版本号 这里给大家分享一下下载链接:https://files.cnb ...

  8. 七、springBoot 简单优雅是实现文件上传和下载

    前言 好久没有更新spring Boot 这个项目了.最近看了一下docker 的知识,后期打算将spring boot 和docker 结合起来.刚好最近有一个上传文件的工作呢,刚好就想起这个脚手架 ...

  9. spring mvc框架+ ajax实现 文件上传

    1.前端页面,通过form表单提交,必须设置 enctype="multipart/form-data" 代表form表单在发送到服务器时候编码方式是二进制类型,一般用于图片.mp ...

  10. 学习SpringMVC必知必会(7)~springmvc的数据校验、表单标签、文件上传和下载

    输入校验是 Web 开发任务之一,在 SpringMVC 中有两种方式可以实现,分别是使用 Spring 自带的验证 框架和使用 JSR 303 实现, 也称之为 spring-validator 和 ...

随机推荐

  1. 天翼云CDR基本概念

    本文分享自天翼云开发者社区<天翼云CDR基本概念>,作者:f****n 产品定义 云容灾CT-CDR(Cloud Disaster Recovery)为云主机提供跨可用区的容灾保护能力,R ...

  2. 流程控制之switch选择结构

    实现方式:switch case语句 switch case语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支 switch语句中的变量类型可以是: byte.short.int或者cha ...

  3. 利用纯JS导出到EXCEL

    var tableToExcel = (function () { var uri = 'data:application/vnd.ms-excel;base64,', template = '< ...

  4. 福尼斯焊机TPS320i/TPS400i/TPS500i的焊接特性

    福尼斯焊机设备原理 TPS320i.TPS400i.TPS500i和TPS 600iMIG/MAG电源由微处理器控制,机器人驱动器维修,是完全数字化的逆变器电源. 模块化设计和系统的扩展潜力使其具有高 ...

  5. AI 艺术工具通讯

    创刊号 AI 领域的发展速度令人惊叹,回想一年前我们还在为生成正确手指数量的人像而苦苦挣扎的场景,恍如隔世 . 过去两年对开源模型和艺术创作工具而言具有里程碑意义.创意表达的 AI 工具从未像现在这般 ...

  6. Flink - [03] API

    使用scala编写flink api从不同的数据源(源端)读取数据,并进行无界流/有界流的数据处理,最终将处理好的数据sink到对应的目标端 一.maven配置 <?xml version=&q ...

  7. Ansible - [06] Playbook

    Playbook 概述 Ansible ad-hoc 可以通过命令行形式远程管理其他主机 适合执行一些临时性简单任务 Ansible playbook 中文名称叫 剧本 将经常需要执行的任务写入一个文 ...

  8. npm配置

    在 Node.js 中,npm(Node Package Manager)是 JavaScript 包的默认管理工具.要查看 npm 的配置,你可以使用 npm config 命令配合不同的子命令来获 ...

  9. 自己写的第一个java项目!

    项目名为"零钱通" 细节参考 [零基础 快速学Java]韩顺平 零基础30天学会Java 基本版: 1 package project; 2 3 import java.text. ...

  10. 一个ABAQUS model需要的Component

    component of abaqus model Abaqus模型由几个不同的组件组成,它们共同描述了要分析的物理问题. a abaqus model 至少要有: discrete goemtry ...