当前位置: 首页 > news >正文

做团购网站哪家好些惠州百度seo找谁

做团购网站哪家好些,惠州百度seo找谁,重庆网上办事大厅,重庆网站建设招聘信息转载自 OAuth2 实现单点登录 SSO 1. 前言 技术这东西吧#xff0c;看别人写的好像很简单似的#xff0c;到自己去写的时候就各种问题#xff0c;“一看就会#xff0c;一做就错”。网上关于实现SSO的文章一大堆#xff0c;但是当你真的照着写的时候就会发现根本不是那么…转载自  OAuth2 实现单点登录 SSO 1. 前言 技术这东西吧看别人写的好像很简单似的到自己去写的时候就各种问题“一看就会一做就错”。网上关于实现SSO的文章一大堆但是当你真的照着写的时候就会发现根本不是那么回事儿简直让人抓狂尤其是对于我这样的菜鸟。几经曲折终于搞定了决定记录下来以便后续查看。先来看一下效果 2. 准备 2.1. 单点登录 最常见的例子是我们打开淘宝APP首页就会有天猫、聚划算等服务的链接当你点击以后就直接跳过去了并没有让你再登录一次 下面这个图是我再网上找的我觉得画得比较明白 可惜有点儿不清晰于是我又画了个简版的 重要的是理解 SSO服务端和SSO客户端直接是通过授权以后发放Token的形式来访问受保护的资源 相对于浏览器来说业务系统是服务端相对于SSO服务端来说业务系统是客户端 浏览器和业务系统之间通过会话正常访问 不是每次浏览器请求都要去SSO服务端去验证只要浏览器和它所访问的服务端的会话有效它就可以正常访问 2.2. OAuth2 推荐以下几篇博客 《OAuth 2.0》 《Spring Security对OAuth2的支持》 3. 利用OAuth2实现单点登录 接下来只讲跟本例相关的一些配置不讲原理不讲为什么 众所周知在OAuth2在有授权服务器、资源服务器、客户端这样几个角色当我们用它来实现SSO的时候是不需要资源服务器这个角色的有授权服务器和客户端就够了。 授权服务器当然是用来做认证的客户端就是各个应用系统我们只需要登录成功后拿到用户信息以及用户所拥有的权限即可 之前我一直认为把那些需要权限控制的资源放到资源服务器里保护起来就可以实现权限控制其实是我想错了权限控制还得通过Spring Security或者自定义拦截器来做 3.1. Spring Security 、OAuth2、JWT、SSO 在本例中一定要分清楚这几个的作用 首先SSO是一种思想或者说是一种解决方案是抽象的我们要做的就是按照它的这种思想去实现它 其次OAuth2是用来允许用户授权第三方应用访问他在另一个服务器上的资源的一种协议它不是用来做单点登录的但我们可以利用它来实现单点登录。在本例实现SSO的过程中受保护的资源就是用户的信息包括用户的基本信息以及用户所具有的权限而我们想要访问这这一资源就需要用户登录并授权OAuth2服务端负责令牌的发放等操作这令牌的生成我们采用JWT也就是说JWT是用来承载用户的Access_Token的 最后Spring Security是用于安全访问的这里我们我们用来做访问权限控制 4. 认证服务器配置 4.1. Maven依赖 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.1.3.RELEASE/versionrelativePath/ !-- lookup parent from repository --/parentgroupIdcom.cjs.sso/groupIdartifactIdoauth2-sso-auth-server/artifactIdversion0.0.1-SNAPSHOT/versionnameoauth2-sso-auth-server/namepropertiesjava.version1.8/java.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-jpa/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependencydependencygroupIdorg.springframework.security.oauth.boot/groupIdartifactIdspring-security-oauth2-autoconfigure/artifactIdversion2.1.3.RELEASE/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.session/groupIdartifactIdspring-session-data-redis/artifactId/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.springframework.security/groupIdartifactIdspring-security-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactIdversion3.8.1/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.56/version/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build/project这里面最重要的依赖是spring-security-oauth2-autoconfigure 4.2. application.yml spring:datasource:url: jdbc:mysql://localhost:3306/permissionusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverjpa:show-sql: truesession:store-type: redisredis:host: 127.0.0.1password: 123456port: 6379 server:port: 80804.3. AuthorizationServerConfig重要 package com.cjs.sso.config;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.security.core.token.DefaultToken; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;import javax.sql.DataSource;/*** author ChengJianSheng* date 2019-02-11*/ Configuration EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {Autowiredprivate DataSource dataSource;Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {security.allowFormAuthenticationForClients();security.tokenKeyAccess(isAuthenticated());}Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.jdbc(dataSource);}Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.accessTokenConverter(jwtAccessTokenConverter());endpoints.tokenStore(jwtTokenStore()); // endpoints.tokenServices(defaultTokenServices());}/*PrimaryBeanpublic DefaultTokenServices defaultTokenServices() {DefaultTokenServices defaultTokenServices new DefaultTokenServices();defaultTokenServices.setTokenStore(jwtTokenStore());defaultTokenServices.setSupportRefreshToken(true);return defaultTokenServices;}*/Beanpublic JwtTokenStore jwtTokenStore() {return new JwtTokenStore(jwtAccessTokenConverter());}Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter() {JwtAccessTokenConverter jwtAccessTokenConverter new JwtAccessTokenConverter();jwtAccessTokenConverter.setSigningKey(cjs); // Sets the JWT signing keyreturn jwtAccessTokenConverter;}}说明 别忘了**EnableAuthorizationServer** Token存储采用的是JWT 客户端以及登录用户这些配置存储在数据库为了减少数据库的查询次数可以从数据库读出来以后再放到内存中 4.4. WebSecurityConfig重要 package com.cjs.sso.config;import com.cjs.sso.service.MyUserDetailsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;/*** author ChengJianSheng* date 2019-02-11*/ Configuration EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter {Autowiredprivate MyUserDetailsService userDetailsService;Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());}Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers(/assets/**, /css/**, /images/**);}Overrideprotected void configure(HttpSecurity http) throws Exception {http.formLogin().loginPage(/login).and().authorizeRequests().antMatchers(/login).permitAll().anyRequest().authenticated().and().csrf().disable().cors();}Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}}4.5. 自定义登录页面一般来讲都是要自定义的 package com.cjs.sso.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping;/*** author ChengJianSheng* date 2019-02-12*/ Controller public class LoginController {GetMapping(/login)public String login() {return login;}GetMapping(/)public String index() {return index;}}自定义登录页面的时候只需要准备一个登录页面然后写个Controller令其可以访问到即可登录页面表单提交的时候method一定要是post最重要的时候action要跟访问登录页面的url一样 千万记住了访问登录页面的时候是GET请求表单提交的时候是POST请求其它的就不用管了 !DOCTYPE html html xmlns:thhttp://www.thymeleaf.org headmeta charsetutf-8meta http-equivX-UA-Compatible contentIEedgetitleEla Admin - HTML5 Admin Template/titlemeta namedescription contentEla Admin - HTML5 Admin Templatemeta nameviewport contentwidthdevice-width, initial-scale1link typetext/css relstylesheet th:href{/assets/css/normalize.css}link typetext/css relstylesheet th:href{/assets/bootstrap-4.3.1-dist/css/bootstrap.min.css}link typetext/css relstylesheet th:href{/assets/css/font-awesome.min.css}link typetext/css relstylesheet th:href{/assets/css/style.css}/head body classbg-darkdiv classsufee-login d-flex align-content-center flex-wrapdiv classcontainerdiv classlogin-contentdiv classlogin-logoh1 stylecolor: #57bf95;欢迎来到王者荣耀/h1/divdiv classlogin-formform th:action{/login} methodpostdiv classform-grouplabelUsername/labelinput typetext classform-control nameusername placeholderUsername/divdiv classform-grouplabelPassword/labelinput typepassword classform-control namepassword placeholderPassword/divdiv classcheckboxlabelinput typecheckbox Remember Me/labellabel classpull-righta href#Forgotten Password?/a/label/divbutton typesubmit classbtn btn-success btn-flat m-b-30 m-t-30 stylefont-size: 18px;登录/button/form/div/div/div /divscript typetext/javascript th:src{/assets/js/jquery-2.1.4.min.js}/script script typetext/javascript th:src{/assets/bootstrap-4.3.1-dist/js/bootstrap.min.js}/script script typetext/javascript th:src{/assets/js/main.js}/script/body /html4.6. 定义客户端 4.7. 加载用户 登录账户 package com.cjs.sso.domain;import lombok.Data; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.User;import java.util.Collection;/*** 大部分时候直接用User即可不必扩展* author ChengJianSheng* date 2019-02-11*/ Data public class MyUser extends User {private Integer departmentId; // 举个例子部门IDprivate String mobile; // 举个例子假设我们想增加一个字段这里我们增加一个mobile表示手机号public MyUser(String username, String password, Collection? extends GrantedAuthority authorities) {super(username, password, authorities);}public MyUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection? extends GrantedAuthority authorities) {super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);} }加载登录账户 package com.cjs.sso.service;import com.alibaba.fastjson.JSON; import com.cjs.sso.domain.MyUser; import com.cjs.sso.entity.SysPermission; import com.cjs.sso.entity.SysUser; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils;import java.util.ArrayList; import java.util.List;/*** author ChengJianSheng* date 2019-02-11*/ Slf4j Service public class MyUserDetailsService implements UserDetailsService {Autowiredprivate PasswordEncoder passwordEncoder;Autowiredprivate UserService userService;Autowiredprivate PermissionService permissionService;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {SysUser sysUser userService.getByUsername(username);if (null sysUser) {log.warn(用户{}不存在, username);throw new UsernameNotFoundException(username);}ListSysPermission permissionList permissionService.findByUserId(sysUser.getId());ListSimpleGrantedAuthority authorityList new ArrayList();if (!CollectionUtils.isEmpty(permissionList)) {for (SysPermission sysPermission : permissionList) {authorityList.add(new SimpleGrantedAuthority(sysPermission.getCode()));}}MyUser myUser new MyUser(sysUser.getUsername(), passwordEncoder.encode(sysUser.getPassword()), authorityList);log.info(登录成功用户: {}, JSON.toJSONString(myUser));return myUser;} }4.8. 验证 当我们看到这个界面的时候表示认证服务器配置完成 5. 两个客户端 5.1. Maven依赖 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.1.3.RELEASE/versionrelativePath/ !-- lookup parent from repository --/parentgroupIdcom.cjs.sso/groupIdartifactIdoauth2-sso-client-member/artifactIdversion0.0.1-SNAPSHOT/versionnameoauth2-sso-client-member/namedescriptionDemo project for Spring Boot/descriptionpropertiesjava.version1.8/java.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-jpa/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-oauth2-client/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependencydependencygroupIdorg.springframework.security.oauth.boot/groupIdartifactIdspring-security-oauth2-autoconfigure/artifactIdversion2.1.3.RELEASE/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId/dependencydependencygroupIdorg.thymeleaf.extras/groupIdartifactIdthymeleaf-extras-springsecurity5/artifactIdversion3.0.4.RELEASE/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdcom.h2database/groupIdartifactIdh2/artifactIdscoperuntime/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.springframework.security/groupIdartifactIdspring-security-test/artifactIdscopetest/scope/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build/project5.2. application.yml server:port: 8082servlet:context-path: /memberSystem security:oauth2:client:client-id: UserManagementclient-secret: user123access-token-uri: http://localhost:8080/oauth/tokenuser-authorization-uri: http://localhost:8080/oauth/authorizeresource:jwt:key-uri: http://localhost:8080/oauth/token_key这里context-path不要设成/不然重定向获取code的时候回被拦截 5.3. WebSecurityConfig package com.cjs.example.config;import com.cjs.example.util.EnvironmentUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;/*** author ChengJianSheng* date 2019-03-03*/ EnableOAuth2Sso Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter {Autowiredprivate EnvironmentUtils environmentUtils;Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers(/bootstrap/**);}Overrideprotected void configure(HttpSecurity http) throws Exception {if (local.equals(environmentUtils.getActiveProfile())) {http.authorizeRequests().anyRequest().permitAll();}else {http.logout().logoutSuccessUrl(http://localhost:8080/logout).and().authorizeRequests().anyRequest().authenticated().and().csrf().disable();}} }说明 最重要的注解是EnableOAuth2Sso 权限控制这里采用Spring Security方法级别的访问控制结合Thymeleaf可以很容易做权限控制 顺便多提一句如果是前后端分离的话前端需求加载用户的权限然后判断应该显示那些按钮那些菜单 5.4. MemberController package com.cjs.example.controller;import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import java.security.Principal;/*** author ChengJianSheng* date 2019-03-03*/ Controller RequestMapping(/member) public class MemberController {GetMapping(/list)public String list() {return member/list;}GetMapping(/info)ResponseBodypublic Principal info(Principal principal) {return principal;}GetMapping(/me)ResponseBodypublic Authentication me(Authentication authentication) {return authentication;}PreAuthorize(hasAuthority(member:save))ResponseBodyPostMapping(/add)public String add() {return add;}PreAuthorize(hasAuthority(member:detail))ResponseBodyGetMapping(/detail)public String detail() {return detail;} }5.5. Order项目跟它是一样的 server:port: 8083servlet:context-path: /orderSystem security:oauth2:client:client-id: OrderManagementclient-secret: order123access-token-uri: http://localhost:8080/oauth/tokenuser-authorization-uri: http://localhost:8080/oauth/authorizeresource:jwt:key-uri: http://localhost:8080/oauth/token_key5.6. 关于退出 退出就是清空用于与SSO客户端建立的所有的会话简单的来说就是使所有端点的Session失效如果想做得更好的话可以令Token失效但是由于我们用的JWT故而撤销Token就不是那么容易关于这一点在官网上也有提到 本例中采用的方式是在退出的时候先退出业务服务器成功以后再回调认证服务器但是这样有一个问题就是需要主动依次调用各个业务服务器的logout 6. 工程结构 附上源码https://github.com/chengjiansheng/cjs-oauth2-sso-demo.git 7. 演示 8. 参考 https://www.cnblogs.com/cjsblog/p/9174797.html https://www.cnblogs.com/cjsblog/p/9184173.html https://www.cnblogs.com/cjsblog/p/9230990.html https://www.cnblogs.com/cjsblog/p/9277677.html https://blog.csdn.net/fooelliot/article/details/83617941 http://blog.leapoahead.com/2015/09/07/user-authentication-with-jwt/ https://www.cnblogs.com/lihaoyang/p/8581077.html https://www.cnblogs.com/charlypage/p/9383420.html http://www.360doc.com/content/18/0306/17/16915_734789216.shtml https://blog.csdn.net/chenjianandiyi/article/details/78604376 https://www.baeldung.com/spring-security-oauth-jwt https://www.baeldung.com/spring-security-oauth-revoke-tokens https://www.reinforce.cn/t/630.html 9. 文档 https://projects.spring.io/spring-security-oauth/docs/oauth2.html https://docs.spring.io/spring-security-oauth2-boot/docs/2.1.3.RELEASE/reference/htmlsingle/ https://docs.spring.io/spring-security-oauth2-boot/docs/2.1.3.RELEASE/ https://docs.spring.io/spring-security-oauth2-boot/docs/ https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/ https://docs.spring.io/spring-boot/docs/ https://docs.spring.io/spring-framework/docs/ https://docs.spring.io/spring-framework/docs/5.1.4.RELEASE/ https://spring.io/guides/tutorials/spring-boot-oauth2/ https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#core-services-password-encoding https://spring.io/projects/spring-cloud-security https://cloud.spring.io/spring-cloud-security/single/spring-cloud-security.html https://docs.spring.io/spring-session/docs/current/reference/html5/guides/java-security.html https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-redis.html#boot-spring-configuration
http://www.pierceye.com/news/115357/

相关文章:

  • 做此广告的网站做家纺的网站
  • 湖南畅想网站建设个人网站建设基本定位
  • 建站公司外包钓鱼网站怎么做
  • 个人网站logo需要备案吗鑫灵锐做网站多少钱
  • .xyz做网站怎么样网站产品预算
  • 建网站先要申请网址吗做网站给文件不侵权
  • 一元夺宝网站建设Wordpress 普通图片裁剪
  • 网站推广都有哪些自己有网站怎么优化
  • 宠物交易网站模板更改wordpress后台登录地址
  • 有电脑网站怎样建手机正规网络游戏平台
  • 网站抓取QQ获取系统cms监控手机客户端
  • 郑州网站推广价格优礼品网站模板
  • 百度指数不高的网站怎么优化网站图片类型
  • 北京专业做网站怎么样app软件开发摄像头
  • 网站建设导向erp系统软件免费版
  • 手表网站网站开发毕业设计文献综述
  • 台州网站制作维护关于微网站策划ppt怎么做
  • 网站建设中期目标开发app找那个公司
  • 跨境自建站模板网站内容和功能清单
  • 平面设计找素材的网站电子商务网站建设的步骤一般为(
  • 一个服务器可以备案几个网站凡科门店通怎么样
  • 房地产企业网站建设想给公司产品做个推广
  • 国外网站平台wordpress电脑安装教程
  • 网站开发合肥诚聘网站开发人员
  • 网站开发者模式怎么保存网站首页调用网站标题
  • 仿京东网站模板wordpress单页视差
  • php mysql 网站建设html5手机网站模板
  • 山楂树建站公司建筑方案设计说明模板
  • 服务器网站源码在哪建筑电工证
  • 网站导航国外做名片网站