精华内容
下载资源
问答
  • 该系统将观众席预订记录以及相关事件详细信息客户联系人保存在一个维护良好的数据库中。 管理员可以轻松地在系统图形用户界面(GUI)中检查礼堂预定时间安排。 当新事件时间临近或冲突时,系统也会通知...
  • STAFFI使用图形用户界面来存储处理有关志愿者,筹款活动捐赠数据。 STAFFI能够将信息实时传递到网页,并提供了强大工具,可通过电子邮件邮寄大量联系支持者。
  • 双向视频流市场平台,具有信用卡支付功能,用户角色管理,复杂的用户界面和高级数据库关系。 使用Stripe集成Javascript,JSON,Ajax请求安全支付功能。 HTML5,CSS,Ruby,Rails,算法,Javascript 目录 基本信息 ...
  • “简单状态”是一个单页面应用程序,并且是一个无所不包平台,可以立即访问最新Covid统计信息,州情况,美国参议员的联系信息以及经过过滤新闻搜索。 屏幕截图 登录注册页面 完整首页 地图选择按钮选项...
  • 系统主要实现一些VB的数据库操作,比如新建人员信息、删除、查找用户信息、系统维护设置等功能,用VB写出这样的界面和功能非常不错的源代码,附件包中使用了一些控件。 小提示:系统登陆的用户名是:admin,密码...
  • 用户在这里就指操作人员,已经在人员档案中进行管理,通过设计用户登录和用户权限管理,实现用户按权限访问资源,管理员按要求授予用户权限,登录程序安全稳定,设计用户菜单及程序调用。人员表中需要新增字段口令...
  • 血库管理系统是所有献血问题解决方案,该系统访问权限仅授予管理员和用户,它为用户提供了非常友好用户界面。 管理员功能是查看详细信息,接受/拒绝正在注册用户未决请求,更新映射详细信息和修改数据库...
  • 5.2.3 关系数据库和关系数据库模式 103 5.2.4 实体完整性、参照完整性和外码 104 5.2.5 其他类型约束 106 5.3 更新操作、事务和处理违例约束 107 5.3.1 插入操作 107 5.3.2 删除操作 108 ...
  • 1.2.1 数据库和模式 6 1.2.2 表、行和列 7 1.2.3 信息原则 10 1.2.4 域 12 1.2.5 元数据 13 1.2.6 键 13 1.2.7 未显式赋值项(NULL) 18 1.3 实体之间关系 20 1.3.1 二元关系 21 1.3.2 非二元关系 24 ...
  • 1.2.1 数据库和模式 6 1.2.2 表、行和列 7 1.2.3 信息原则 10 1.2.4 域 12 1.2.5 元数据 13 1.2.6 键 13 1.2.7 未显式赋值项(NULL) 18 1.3 实体之间关系 20 1.3.1 二元关系 21 1.3.2 非二元关系 24 ...
  • 2.数据库连接参数设置,用户登录,密码修改,权限设置,金蝶KIS...如果这里的数据库连接参数不知道是多少,那么请联系我们技术支持给您远程协助,通过远程协助您服务器电脑来查看数据库连接参数,然后把数据库连接.

    2.数据库连接参数设置,用户登录,密码修改,权限设置,金蝶KIS旗舰版安卓盘点机PDA

     

    本期视频我们来讲解一下盘点机PDA数据库连接参数设置,用户登录,密码修改,和权限设置等方面的操作:
    1.数据库连接参数设置:
    系统主界面打开PDA程序,在登录界面,点击右下角的【连接设置】进入数据库参数设置界面,录入服务器的IP地址,数据端口,数据库用户名,数据库用户密码。如果这里的数据库连接参数不知道是多少,那么请联系我们的技术支持给您远程协助,通过远程协助您的服务器电脑来查看数据库连接参数,然后把数据库连接参数告诉您,您自己填上这些参数即可)
    填好数据库连接参数后,点击数据库名右边的【选择】按钮,进入数据库列表选择界面,选择相应的账套数据库,点击保存,显示连接成功。
    2.用户登录:
    登录界面点击登录模式切换开关,切换到在线模式,PDA会获取金蝶里的用户,点击用户,选择需要登录的用户,录入密码(密码跟电脑金蝶里的登录密码一致)。点击【登录】即可登录到主菜单界面。
    注意:首次登录会自动运行版本差异处理,点击确定即可。
    3.用户密码修改:
    在【主菜单】界面,点击【系统设置】,点击【权限设定】,输入管理密码999,点击【确定】,点击【获取用户】显示用户列表,长按需要修改密码的用户,弹出密码修改界面,录入新密码,点击确定即可。
    4.用户权限设置
       在这个界面,点击用户,则进入该用户的权限设置界面,这里有单据权限,功能权限,单价权限,仓库权限等。比如可以设置某个用户不能使用PDA的某个单据模块功能,设置某个用户不能看到进价,库存等信息的权限。权限设置非常丰富,大家可以详细研究下。

    有不明白的,请随时联系我们盘点机PDA的技术支持。谢谢关注,点赞,评论,转发
     

    展开全文
  • spring security 简单入门 自定义登录界面、登录验证、登录成功处理、登录失败处理 学习,我相信大家一定对 Spring Security 有了很很深刻认识,但是也肯定不满足于前面基于内存方式存储用户信息。...

    经过前面两篇文章的学习 (spring security 简单入门自定义登录界面、登录验证、登录成功处理、登录失败处理) ,我相信大家一定对 Spring Security 有了很很深刻的认识,但是也肯定不满足于前面的基于内存的方式存储用户信息。所以,本篇文章,我们就专门来讨论一下从数据库获取用户并进行用户的身份验证如何实现。

    本文主要介绍如何让 Spring Security 与我们的数据库中的用户产生联系,对于用户的权限部分,我只采用很简单的方式,将权限直接放在用户表中。在后面的文章中,我将详细介绍如何设计 RBAC 用户角色权限。

    【示例代码说明】本文的代码是建立在前一篇文章 自定义登录界面、登录验证、登录成功处理、登录失败处理 的基础上的,如果大家想跟着我的思路一起完成本文的示例,可以先克隆上一篇文章的代码;也可以直接查看本文文末给出的代码示例。

    1 创建数据表

    【说明】 本小节没有直接贴出数据库表,而更多的是介绍了我们为什么要这么做。

    在创建数据表之前,我们有一个点需要产生共识:Spring Security 应该是适应实际项目的,而不是项目适应 Spring Security
    大概意思就是说,我们的项目不能因为加入了 Spring Security 而做出大量的改变,比如我们大范围修改数据库或代码等,而是应该让 Spring Security 适应我们的项目。
    Spring Security 说到底就是一个用户认证 / 授权的组件,我们也可以使用 Shiro ,甚至是我们自己手写代码来完成用户认证 / 授权的功能。
    不论是这三种方式的哪一种,都不应该对我们项目的其他部分提出要求:要改这里,要改那里。

    假如我们的项目已经运行了一段时间了,我们以前使用的登录验证就是我们自己编写的拦截器来验证用户是否登录等。现在,我们发现这样不好做权限控制,想让我们的系统加入 Spring Security 模块,并且我们也不想对我们的用户做出任何的修改。

    这个表就是我们已经运行了一段时间的用户表

    CREATE TABLE `user` (
      `userId` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号',
      `yonghuming` varchar(255) CHARACTER SET latin1 NOT NULL COMMENT '用户名',
      `mima` varchar(255) CHARACTER SET latin1 NOT NULL COMMENT '密码',
      `age` int(11) DEFAULT NULL COMMENT '年龄',
      `authority` varchar(255) CHARACTER SET latin1 NOT NULL COMMENT '用户角色',
      PRIMARY KEY (`userId`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
    

    我们插入两个用户:

    insert into user(username,password,age,authority) VALUE('llk','$10$Cn1WZ1zQLAf8L5rqEmNq2e7.3zpnH1isprkexi7rRYARnXPrjIIrq','23','USER');
    insert into user(yonghuming,mima,age,authority) VALUE('zhangsan','$10$TapTxIEj3oMOaN/V6lHktuny14yUfL8fJGlmq20U9QRIXncgi.bOO','29','USER,ADMIN');
    

    大家可能发现了,用户名字段我没有用 username 而是用的 yonghuming密码也是如此,这样做的目的的是为了防止大家一会儿与 Spring Security 中的 username 和 password 混淆了,其实他们本质上是一个,只是做个区分。
    因为我发现很多人对 Spring Security 若即若离,就是因为这些不必要的混淆干扰到他了。这是也告诉大家,数据库中的字段大家可以随便定义,想怎么写就可以怎么写,不需要完全与 Spring Security 中的 username 和 password 一样。当然这两种之间是要进行必要的关联的,我们后面会讲到。

    其中 authority 字段是用户的权限,该字段是一个 varchar 类型,多个权限是用逗号拼接在一起的,不一定是逗号,别的符号也可以,这取决于你自己。我们后面需要将这个字符串进行拆分成数组,再封装成集合,然后交给 Spring Security

    其中的 age 字段,我们可以把它相成别的任意字段,用户描述信息、用户性别、用户地址等等。

    上面 insert 语句中,我们的密码是 BCrypt 算法加过密的。我们可以通过下面的方式让我们的明文密码进行加密。
    创建一个测试类:

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = Application.class)
    public class BCryptTest {
    
        @Autowired
        private PasswordEncoder passwordEncoder;
    
        @Test
        public void encode(){
            String encode = passwordEncoder.encode("123456");
            System.out.println(encode);
        }
    }
    

    2 编写用户类

    2.1 认识 UserDetails

    经过前一篇文章的学习,我们了解到 Spring Security 的 AuthenticationProvider 在验证用户的密码时,用的是 UserDetails ,UserDetails 是服务器保存用户的用户名、密码、以及权限的类
    所以我们自己直接编写的 User 类,AuthenticationProvider 是不认的,我们需要让我们的 User 类变成 AuthenticationProvider 能够认识的 UserDetails

    UserDetails 其实是一个接口:

    public interface UserDetails extends Serializable {
    	//用户具有的权限
    	Collection<? extends GrantedAuthority> getAuthorities();
    	//密码 
    	String getPassword();
    	//用户名
    	String getUsername();
    	//用户是否失效
    	boolean isAccountNonExpired();
    	//用户是否被锁定
    	boolean isAccountNonLocked();
    	//用户的密码是否失效
    	boolean isCredentialsNonExpired();
    	//用户是否可用
    	boolean isEnabled();
    }
    

    这些方法都是在用户认证时或权限验证会被调用的,这些方法的作用就是将我们数据库中的值交给 AuthenticationProvider 。使我们的 yonghuming 与 username 建立关系mima 与 password 建立关系的地方

    其中后四个方法,在我们的示例代码中不会用到,我们都默认返回 true ,表示用户没有被锁定、用户可用等。大家可以根据自己的实际情况做出改变,具体做法可以参照后面 yonghuming 的做法。

    2.2 编写 User 类

    经过前面的分析,我们的 User 类 需要实现 UserDetails 接口
    User.java:

    public class User implements UserDetails {
    
        private Integer userId;
        private String yonghuming;
        private String mima;
        private int age;
        private String authority;
    
        //将我们的 权限字符串进行分割,并存到集合中,最后供 AuthenticationProvider 使用
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            String[] authorities = this.authority.split(",");
            ArrayList<GrantedAuthority> list = new ArrayList();
            for(int i = 0;i<authorities.length;i++){
                int finalI = i;
                GrantedAuthority grantedAuthority = new GrantedAuthority() {
                    @Override
                    public String getAuthority() {
                        return authorities[finalI];
                    }
                };
                list.add(grantedAuthority);
            }
            return list;
        }
    
        //将我们的 mima 转换成 AuthenticationProvider 能够认识的 password
        @Override
        public String getPassword() {
            return this.mima;
        }
    
        //将我们的 yonghuming 转换成 AuthenticationProvider 能够认识的 username
        @Override
        public String getUsername() {
            return this.yonghuming;
        }
    
        public Integer getUserId() {
            return userId;
        }
    
        public void setUserId(Integer userId) {
            this.userId = userId;
        }
    
        public String getYonghuming() {
            return yonghuming;
        }
    
        public void setYonghuming(String yonghuming) {
            this.yonghuming = yonghuming;
        }
    
        public String getMima() {
            return mima;
        }
    
        public void setMima(String mima) {
            this.mima = mima;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getAuthority() {
            return authority;
        }
    
        public void setAuthority(String authority) {
            this.authority = authority;
        }
    
        //都返回 true
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            return true;
        }
    }
    

    大家可以把我们的 User 类当做是一个适配器,我们只有 yonghuming 和 mima 这样的字段,但是 Spring Security 不认识,它只认识 username 和 password ,所以我们需要实现 UserDetails 的 getUsername() 和 getPassword() 方法将我们的 yonghuming 和 mima 字段的值交给 Spring Security。

    对于权限字段也是如此,我们只有 “ADMIN,USER” 这样的权限字符串,但是 Spring Security 不认识这样的字符串,所以我们需要将字符串转换成它能认识的 Collection 集合。

    3 完成 mapper 相关工作

    由于我们的用户是存储在数据库的,所以我们使用 mybatis 从我们的数据库中获取数据。

    本部分只做示例,所以很多地方都很简单,只是保证能使用就行。

    第一步,引入 mybatis 相关的依赖:

    	<dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.2.0</version>
            </dependency>
    

    第二步,在 application.yml 中配置数据库相关信息:

    spring:
      datasource:
        username: root
        password: root
        url: jdbc:mysql://192.168.1.184:3306/securityDemoThree?useUnicode=true&characterEncoding=utf-8
        driver-class-name: com.mysql.cj.jdbc.Driver
    
    mybatis:
      mapper-locations: classpath:mapper/*Mapper.xml
    

    第三步,编写 mapper :

    @Mapper
    public interface UserMapper {
    
        @Select("select * from user where yonghuming = #{yonghuming}")
        public User getByUsername(@Param("yonghuming") String yonghuming);
    }
    

    4 实现 UserDetailsService

    4.1 为什么要实现 UserDetailsService

    在上一篇文章中我们 自定义 AuthenticationProvider 实现登录验证时,我们在 MyAuthenticationProvider 中使用下面的代码来获取服务器保存的用户信息:

    UserDetails userDetails = userDetailsService.loadUserByUsername(userName);
    

    然后与前端用户输入的密码进行比对,来判断是否登录成功。

    当时我们的用户信息是存储在内存中,我们当时是这样配置的:

    	@Bean
        public UserDetailsService userDetailsService() {
            //内存用户管理器,该类最终也实现自 UserDetailsService
            InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
            manager.createUser(User.withUsername("llk").password(passwordEncoder().encode("123")).authorities("USER").build());
            manager.createUser(User.withUsername("zhangsan").password(passwordEncoder().encode("123456")).authorities("USER","ADMIN").build());
            return manager;
        }
    
    	@Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userAuthService);
        }
    

    从上面的代码我们可以看出,AuthenticationProvider 在认证用户时需要使用 userDetailsService 的 loadUserByUsername() 方法来获取 UserDetails ,所以我们需要注册一个可以获取用户信息的 userDetailsService 实例到容器中,并且通过 auth.userDetailsService(userAuthService); 配置告诉 Spring Security 使用我们自己定义的 userDetailsService 。

    所以现在我们也需要编写我们自己的 userDetailsService ,并将它注册到容器中。

    我们查看源码发现,UserDetailsService 其实是一个接口:

    public interface UserDetailsService {
    	UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
    }
    

    该接口就一个方法,loadUserByUsername(String username)。

    4.2 实现 UserDetailsService

    第一步,实现 UserDetailsService 接口:

    编写 UserAuthService 类并实现 UserDetailsService 接口:
    UserAuthService.java:

    @Component
    public class UserAuthService implements UserDetailsService {
        @Autowired
        private UserMapper userMapper;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = userMapper.getByUsername(username);
            if(user == null){
                throw new UsernameNotFoundException("not found the user:"+username);
            }
            return user;
        }
    }
    

    该段代码,我写的很简单,目的是让大家能够一目了然。在 loadUserByUsername() 方法中,我们使用我们的 userMapper 从数据库中获取用户数据,然后直接返回即可
    所以这里就可以很灵活了,如果在你的实际场景里,用户信息是保存在 redis 中、或是需要从别的服务器获取用户信息,都可以在该方法中完成,只需要保证返回的是 UserDetails 类型即可
    我们这里因为我们的 User 类已经实现了 UserDetails 并将字段都做过转换,所以可以直接返回。

    如果你的 User 类没有实现 UserDetails ,那么你还可以通过第二种方式返回 UserDetails 。
    在 loadUserByUsername() 方法中创建一个 User 对象(注意:是 org.springframework.security.core.userdetails 包下的 User),该类有多个构造方法,你直接将你的用户信息传递该它的构造方法即可。

    经过前面的代码编写,实现 UserDetailsService 接口的任务我们就完成了。接下来就是要让 Spring Security 使用我们自定义的 UserAuthService 。

    第二步、在 WebSecurityConfiguration.java 中做如下配置:

    如果大家是在我上一篇文章的代码基础上做修改的话,我们需要将之前配置的 UserDetailsService 给注释。

    注入我们的 UserAuthService :

    	@Autowired
        private UserAuthService userAuthService;
    

    将 UserAuthService 配置给 Spring Security:

    	@Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userAuthService);
        }
    

    到此为止所有的编码工作都完成,我们重启项目,进行测试。

    主要验证用户是否能登录,权限控制是否起作用。

    测试的截图,我就不贴了,和前面的两篇文章差不多。

    5 示例代码

    示例代码地址:spring-security-oauth-demo-three

    本文示例代码项目结构图:
    在这里插入图片描述

    展开全文
  • 本系统采用基于Windows图形用户界面,而该系统是大家熟悉操作系统,对于那些有一般计算机知识人员就可以轻松上手。而整个超市管理系统采用最友好交互界面,简介明了,不需要对数据库进行深入了解。 在本...
  • 8.1.1 主动数据库和Oracle触发器一般模型 145 8.1.2 主动数据库设计和实现 148 8.1.3 STARBURST系统中使用语句级主动规则示例 150 8.1.4 主动数据库潜在应用 151 8.1.5 SQL-99中...
  • 本高校班级管理系统主要目的是为了方便毕业之后大家保持联系,不会因为彼此分开而使得同学间感情疏远。因此要为班级成员提供一个温馨,友好操作界面,让大家进入系统感觉如同走进家庭般温暖,同时为具有较高...
  • 后退 back.r是由加利福尼亚大学圣地亚哥分校11名学生构建软件工程课程项目。 团队 David Owens-项目经理 ... back.r帮助将提出自己想法人与希望为想法做出贡献联系起来。 它主要是通过将用户区分
  • 可以按数据库任意字段名查找联系人,将查询结果显示在软件主界面的表格中,以便查看联系人详细信息。 按姓名排序、按姓名查询、快速查询。 4.用户信息维护 将用户的操作请求发送至客户端,客户端收到用户操作请求,...
  • Symphytum是一款个人数据库软件,适合希望以简单直观方式管理组织数据每个人,而无需学习复杂的数据库语言软件用户界面。 目录 介绍 Symphytum是免费开源个人数据库软件,用C ++Qt编写,适用于Windows...
  • 数据库习题1

    2020-10-01 23:50:21
    问题: 通过Web界面访问在线服务时,动态页面一般都是使用数据库数据生成。 答案: 正确 2、 问题: 数据模型是数据结构语义概括,比如有( )等等。 A. 层次模型 B. 关系模型 C. 实体-联系模型(E-R模型)D...

    数据库习题1

    1、
    问题: 通过Web界面访问在线服务时,动态页面一般都是使用数据库中的数据生成。
    答案: 正确

    2、
    问题: 数据模型是数据结构和语义的概括,比如有( )等等。
    A. 层次模型 B. 关系模型 C. 实体-联系模型(E-R模型)D. 以上三个都对
    答案: D

    3、
    问题: 应用程序员一般按照( )模式访问数据库中的数据。
    A. 内 B. 外 C. 逻辑 D. 物理
    答案: B

    4、
    问题: 保护管理模块以一种称为“事务”的方式,维护多用户并发访问及故障情况下的数据一致性。
    答案: 正确

    5、
    问题: 数据独立性指的是( )
    答案: 数据的组织存储结构与应用程序独立

    6、
    问题: 数据库管理系统提供访问数据库的语言一般包括( )
    答案: 数据定义语言、数据操作语言、数据保护语言

    7、
    问题: 允许事务并发执行虽能带来性能上的好处,但需要对并发进行管控以保证数据完整性。
    答案: 正确

    8、
    问题: 恢复机制保证并发情况下的数据完整性。
    答案: 错误
    解释: 并发控制针对的是并发,故障的处理是由恢复机制来完成的

    9、
    问题: 并发控制机制能保障故障情况下的数据完整性。
    答案: 错误

    10、
    问题: NoSQL系统利用计算机集群这种新架构来存储和处理大数据。
    答案: 正确

    11、
    问题: 当前的NoSQL系统强调可扩展性和高性能。
    答案: 正确

    展开全文
  • 系统自身还有对已发短信查询功能以及查看SIM卡中收到短信,还为用户提供了电话簿功能,通过电话簿管理,可以将比较常用的联系人及其手机号码添加到数据库中,方便在发送短信时添加接收人。系统安全方面也做了...
  • 通过WEB界面,企业运维人员决策者可以进行任意几台主机或所有主机监控的数据库性能、系统资源使用情况对比,并提供数据库性能资源按不同维度排序功能,以及系统资源Top信息图表,帮助决策者更好发现哪些数据库...
  • 结合首创多次查询叠加技术,将每次查询结果按用户要求叠放在同一界面上,能让用户最有效地分析比较各种查询结果,作出最完善判断与决定。 往来结算:提供最详尽结算方式,系统默认自动匹配结算,也可按单据...
  • 用户可以通过提供的界面在自己的管辖范围内对餐厅进行评分,评论评论。 用户可以找到餐厅的联系方式,营业时间信息。 用户可以将自己添加为餐厅中的另一个客户。 UI的左下方已经预先创建了简单的查询,以便于...
  • 该系统满足了不同权限用户的功能需求,系统主要功能包括:业主信息管理、房产信息管理、社区内容管理、物业收费管理、物业服务管理、服务预约管理、报损报修管理、意见反馈管理、留言交流管理、管理员管理等功能。...
  • 目录 IReach应用 这是一个可克隆应用程序,如果您想要做就是在不直接进行应用程序集成情况下启动并运行新闻简报邮件管理器功能,它将使您...配置数据库的ENV变量(用户,密码主机) 生成一个新MAIL_MANAG
  • 旅游行业快速成长同时,各个行业相互间的联系与竞争也就不断加强。互联网时代大背景环境下,电子信息服务将会是一个最便捷最省力最有效服务方式。这就要求旅游行业能够提供一个综合性服务信息平台,同时...
  •  (2)强大数据处理功能,在一个工作组级别网络环境中,使用Access开发用户数据库管理系统具有传统XBASE(DBASE、FoxBASE统称)数据库系统所无法实现客户服务器(Cient/Server)结构相应的数据库安全...
  • 在08cms强大核心上架构,用户可以根据自已需求自行扩展出很多功能。 [商]具有多种级别vip收费会员,有不同阅读收费价格(阅读点/千字)。 [商]更加专业书架书签功能,最近阅读列表。 [商]连载小说txt下载...
  • 聊天应用 它是一个开源应用程序,具有使用FirebaseNode Js实时消息传递。 注意:我正在开发新版本Android Studio 3.6 不要忘记我频道”,例如视频并分享给您...Firebase用户界面 如果有任何文件,则下载并查看

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,033
精华内容 413
关键字:

数据库和用户联系的界面